2 คะแนน โดย GN⁺ 14 일 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Rust 1.96.0 สามารถติดตั้งได้ด้วย rustup update stable และสามารถมีส่วนร่วมในการตรวจสอบรีลีสถัดไปได้ผ่านช่องทาง beta/nightly
  • ชนิด core::range::Range* ใหม่ใช้ IntoIterator แทน Iterator จึงสามารถ implement Copy ได้ และมีแผนจะเป็นชนิดพื้นฐานของไวยากรณ์ช่วงในอนาคต
  • assert_matches! และ debug_assert_matches! จะแสดงค่าในรูปแบบ Debug เมื่อแพตเทิร์นไม่ตรงกัน ทำให้วิเคราะห์สาเหตุของการทดสอบที่ล้มเหลวได้ง่ายขึ้น
  • เป้าหมาย WebAssembly จะไม่ส่ง --allow-undefined เป็นค่าเริ่มต้นอีกต่อไป ทำให้ สัญลักษณ์ที่ยังไม่ได้กำหนด กลายเป็นข้อผิดพลาดของลิงเกอร์แทนที่จะเป็น import
  • Cargo รวมการแก้ไข CVE-2026-5223 และ CVE-2026-5222 สำหรับผู้ใช้ third-party registry และผู้ใช้ crates.io จะไม่ได้รับผลกระทบ

การเปลี่ยนแปลงสำคัญใน Rust 1.96.0

  • การอัปเดตและช่องทางทดสอบ

    • ผู้ใช้ที่ติดตั้ง Rust เดิมด้วย rustup สามารถรับ Rust 1.96.0 ได้ด้วย rustup update stable
    • หากยังไม่มี rustup สามารถติดตั้งได้จาก หน้าติดตั้ง rustup บนเว็บไซต์ Rust และมีการเผยแพร่ บันทึกประจำรุ่นฉบับเต็มของ 1.96.0 แล้ว
    • หากต้องการมีส่วนร่วมในการตรวจสอบรีลีสในอนาคต สามารถใช้ ช่องทาง beta/nightly ได้ด้วย rustup default beta หรือ rustup default nightly และรายงานบั๊กได้ที่ Rust issue tracker
  • ชนิด Range* ใหม่

    • เดิมที Range และชนิดที่เกี่ยวข้องใน core::ops เป็นสิ่งที่ผู้ใช้จำนวนมากคาดหวังว่าจะเป็น Copy แต่เนื่องจากมีการ implement Iterator โดยตรง จึงไม่ได้ implement Copy ร่วมด้วย
    • แนวทาง implement ทั้ง Iterator และ Copy บนชนิดเดียวกันถือเป็น footgun ที่ Clippy เตือน จึงมีการหลีกเลี่ยงมาโดยตลอด
    • RFC3550 เสนอชนิดช่วงทางเลือกที่ implement IntoIterator แทน Iterator และโครงสร้างนี้ทำให้ชนิดเหล่านี้สามารถ implement Copy ได้ด้วย
    • ในไลบรารีมาตรฐาน มีการทำให้ core::range::Range, core::range::RangeFrom, core::range::RangeInclusive และ iterator ที่เกี่ยวข้องมีสถานะ stable แล้ว
    • ใน Rust เวอร์ชันใกล้เคียงในอนาคต จะมีการเพิ่ม core::range::RangeFull และ core::range::RangeTo ที่ re-export จาก core::ops อีกครั้ง รวมถึง core::range::legacy::* ซึ่งจะเป็นตำแหน่งใหม่ของชนิดช่วงปัจจุบัน
    • ไวยากรณ์ช่วง อย่าง 0..1 ตอนนี้ยังสร้างชนิดแบบ legacy อยู่ แต่ใน edition ถัดไปมีแผนจะเปลี่ยนเป็นชนิดใน core::range
    • การทำให้ stable ครั้งใหม่นี้ช่วยให้สามารถเก็บตัวเข้าถึง slice ไว้ในชนิด Copy ได้โดยไม่ต้องแยก start และ end
    • ตัวอย่าง:
      use core::range::Range;
      
      #[derive(Clone, Copy)]
      pub struct Span(Range<usize>);
      
      impl Span {
          pub fn of(self, s: &str) -> &str {
              &s[self.0]
          }
      }
      
    • RangeInclusive แบบใหม่เปิดเผยฟิลด์ และไม่จำเป็นต้องหลีกเลี่ยงการเปิดเผยสถานะ iterator ที่ใช้หมดแล้วเหมือนเวอร์ชัน legacy
    • ชนิดใหม่นี้ต้องถูกแปลงก่อนเริ่มทำการวนซ้ำ ดังนั้นฟิลด์ที่เปิดเผยจึงไม่เป็นปัญหา
    • ผู้เขียนไลบรารีควรพิจารณาใช้ impl RangeBounds ใน public API เพื่อรองรับทั้งชนิดช่วงแบบ legacy และแบบใหม่
    • หากจำเป็นต้องใช้ชนิดแบบเจาะจง แนะนำให้เลือก ชนิดช่วงใหม่ ซึ่งจะกลายเป็นค่าเริ่มต้นในอนาคต
  • แมโครสำหรับยืนยันการจับคู่แพตเทิร์น

    • แมโครใหม่ assert_matches! และ debug_assert_matches! ใช้ตรวจสอบว่าค่าตรงกับแพตเทิร์นที่กำหนดหรือไม่ และหากไม่ตรงจะ panic พร้อมแสดงค่าในรูปแบบ Debug
    • โดยพื้นฐานแล้วทั้งสองแมโครเทียบเท่ากับ assert!(matches!(..)) และ debug_assert!(matches!(..)) แต่การแสดงค่าตอนล้มเหลวช่วยเพิ่ม ความสามารถในการวินิจฉัย
    • เนื่องจากอาจชนกับ third-party crate ยอดนิยมที่มีแมโครชื่อเดียวกัน จึงไม่ได้ถูกเพิ่มเข้าไปใน standard prelude
    • ก่อนใช้งานต้อง import โดยตรงจาก core หรือ std
    • ตัวอย่าง:
      use core::assert_matches;
      
      /// [Random Number](https://xkcd.com/221/)
      fn get_random_number() -> u32 {
          // chosen by a fair dice roll.
          // guaranteed to be random.
          4
      }
      
      fn main() {
          assert_matches!(get_random_number(), 1..=6);
      }
      
  • การเปลี่ยนแปลงของเป้าหมาย WebAssembly

    • เป้าหมาย WebAssembly จะไม่ส่ง --allow-undefined ไปยังลิงเกอร์อีกต่อไป
    • ระหว่างการลิงก์ สัญลักษณ์ที่ยังไม่ได้กำหนด จะไม่ถูกแปลงเป็น WebAssembly import ของโมดูล "env" แต่จะกลายเป็นข้อผิดพลาดของลิงเกอร์แทน
    • หากสัญลักษณ์ที่เกี่ยวกับการลิงก์ยังไม่ได้กำหนดทั้งหมด โมดูลจะไม่สามารถลิงก์ได้ ซึ่งช่วยจับบั๊กได้เร็วขึ้นและป้องกันปัญหาที่เกิดขึ้นโดยไม่ตั้งใจ เช่น ชื่อสัญลักษณ์ผิด
    • โดยทั่วไปแล้วสัญลักษณ์ที่เกี่ยวกับการลิงก์ที่ยังไม่ได้กำหนดมักชี้ถึงบั๊กในช่วง build หรือการตั้งค่าที่ผิดพลาด
    • หากต้องการพฤติกรรมเดิมโดยตั้งใจ สามารถย้อนกลับได้ด้วย RUSTFLAGS=-Clink-arg=--allow-undefined หรือใช้ #[link(wasm_import_module = "env")] กับบล็อกที่กำหนดสัญลักษณ์ในซอร์สโค้ด
    • การเปลี่ยนแปลงนี้ถูกนำมาใช้ใน Rust 1.96 หลังจาก ประกาศในบล็อกก่อนหน้านี้

API ที่ทำให้ stable และการแก้ไขด้านความปลอดภัย

1 ความคิดเห็น

 
GN⁺ 14 일 전
ความคิดเห็นจาก Lobste.rs
  • รู้สึกว่าอยากมี assert_matches ใช้อยู่เรื่อย ๆ แต่ทุกครั้งก็ต้องชั่งใจว่าจะเพิ่ม crate ใหม่หรือเขียนขึ้นมาเองอีกรอบ
    เพราะงั้นเลยดีใจที่มันเข้าไปอยู่ใน standard library

    • แปลกไหมที่ตื่นเต้นกับการได้ลบวงเล็บหลายร้อยคู่ในเทสต์? ผมว่าไม่เลย
  • ชอบขั้นตอนที่กำลังจะทำให้ช่วงค่าเป็น ชนิด Copy
    บางครั้งผมเคยตกใจที่ต้อง clone ช่วงค่า และมันก็ตรงกับสัญชาตญาณมากกว่าว่า 12..34 ควรเป็นข้อมูลเล็ก ๆ ที่คัดลอกได้
    แต่ถ้ามีหลายชนิดที่ชื่อเดียวกัน ก็แอบกังวลนิดหน่อยว่าเวลาที่ VS Code เพิ่ม use ให้อัตโนมัติครั้งหน้า มันอาจดึงชนิดผิดมา

    A Rust version in the near future will also add [...] core::range::legacy::* as the new home for the current ranges. Range syntax like 0..1 still produces the legacy types for now, but will be updated to core::range types in a future edition.
    ระบบ edition ของ Rust ดูเป็นไอเดียที่ดีมาก

    • เท่าที่รู้ ถ้า import แล้วเกิดความกำกวม code action ของ VS Code น่าจะเปิด ดรอปดาวน์ ให้เลือกว่าจะใช้อันไหน
    • ผมไม่ค่อยคิดว่าปกติเราจำเป็นต้อง import ชนิดแบบนี้บ่อยนัก
      สำหรับผู้ใช้ส่วนใหญ่ ข้อดีของชนิดใหม่คงมีไม่มาก เลยใช้ชนิดเดิมต่อไปได้ และพอถึงขอบเขตของ edition ถัดไปก็จะเปลี่ยนไปใช้ชนิดใหม่ให้อัตโนมัติ
      น่าจะเป็นพวกคนเขียนไลบรารีที่ต้องการรองรับทั้งสองเวอร์ชันอย่างชัดเจนเป็นหลักที่ต้อง import ชนิดเหล่านี้
  • These new macros have not been added to the standard prelude, because they would collide with popular third-party crates that provide macros with the same name. Instead, they should be manually imported from core or std before use.
    อันนี้รู้สึกแปลกนิดหน่อย
    มีแผนจะเปลี่ยนทีหลังไหมนะ? ดูเป็นเรื่องประเภทที่พอ ecosystem ย้ายตามกันแล้ว อย่างเช่นผ่านไปสัก 3 ปี ก็น่าจะอยากปรับเป็น การเก็บกวาดเล็ก ๆ

    • ตรงนี้แหละที่ edition ช่วยได้
      สามารถเปลี่ยน prelude ได้โดยไม่ทำให้โปรเจ็กต์เดิมพัง