1 điểm bởi GN⁺ 4 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Rust 1.96.0 có thể được cài bằng rustup update stable, và việc kiểm chứng các bản phát hành sắp tới có thể tham gia qua kênh beta/nightly
  • Các kiểu core::range::Range* mới triển khai IntoIterator thay vì Iterator, nhờ đó có thể triển khai Copy, và sẽ trở thành kiểu mặc định của cú pháp phạm vi trong tương lai
  • assert_matches!debug_assert_matches! sẽ in kèm biểu diễn Debug của giá trị khi không khớp mẫu, giúp chẩn đoán lỗi kiểm thử dễ hơn
  • Với mục tiêu WebAssembly, --allow-undefined không còn được truyền mặc định nữa, nên symbol chưa được định nghĩa sẽ trở thành lỗi linker thay vì import
  • Cargo bao gồm bản vá cho CVE-2026-5223CVE-2026-5222 dành cho người dùng registry bên thứ ba; người dùng crates.io không bị ảnh hưởng

Những thay đổi chính trong Rust 1.96.0

  • Cập nhật và kênh kiểm thử

  • Các kiểu Range* mới

    • Kiểu Range hiện tại và các kiểu liên quan trong core::ops là thứ nhiều người dùng kỳ vọng có Copy, nhưng vì chúng trực tiếp triển khai Iterator nên không triển khai thêm Copy
    • Cách triển khai đồng thời IteratorCopy cho cùng một kiểu là một footgun mà Clippy cảnh báo, nên trước đây đã tránh cách này
    • RFC3550 đề xuất các kiểu phạm vi thay thế triển khai IntoIterator thay vì Iterator, và với cấu trúc này các kiểu đó cũng có thể triển khai Copy
    • Thư viện chuẩn đã ổn định hóa core::range::Range, core::range::RangeFrom, core::range::RangeInclusive và các iterator liên quan
    • Trong một phiên bản Rust sắp tới gần đây sẽ bổ sung core::range::RangeFull, core::range::RangeTo được tái xuất từ core::ops, cùng core::range::legacy::*, nơi mới của các kiểu phạm vi hiện tại
    • Cú pháp phạm vi như 0..1 hiện tạo ra các kiểu legacy, nhưng trong một edition tương lai sẽ chuyển sang các kiểu core::range
    • Việc ổn định hóa mới này cho phép lưu bộ truy cập slice trong kiểu Copy mà không cần tách startend
    • Ví dụ:
      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 mới công khai các trường, vì không cần tránh việc lộ trạng thái iterator đã cạn như ở phiên bản legacy
    • Các kiểu mới phải được chuyển đổi trước khi bắt đầu lặp, nên việc công khai trường không thành vấn đề
    • Tác giả thư viện nên cân nhắc dùng impl RangeBounds trong API công khai để chấp nhận cả kiểu phạm vi legacy lẫn kiểu mới
    • Nếu cần kiểu cụ thể, khuyến nghị ưu tiên kiểu phạm vi mới, vốn sẽ trở thành mặc định trong tương lai
  • Macro khẳng định khớp mẫu

    • Hai macro mới assert_matches!debug_assert_matches! kiểm tra xem một giá trị có khớp với mẫu cho trước hay không, và nếu không sẽ panic kèm biểu diễn Debug của giá trị đó
    • Về bản chất, hai macro này tương đương assert!(matches!(..))debug_assert!(matches!(..)), nhưng giá trị được in ra khi thất bại giúp cải thiện khả năng chẩn đoán
    • Do có thể xung đột với các crate bên thứ ba phổ biến cũng cung cấp macro cùng tên, chúng không được thêm vào standard prelude
    • Trước khi dùng, cần import trực tiếp từ core hoặc std
    • Ví dụ:
      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);
      }
      
  • Thay đổi với mục tiêu WebAssembly

    • Các mục tiêu WebAssembly không còn truyền --allow-undefined cho linker nữa
    • Khi liên kết, symbol chưa được định nghĩa sẽ không còn được chuyển thành WebAssembly import của module "env", mà sẽ trở thành lỗi linker
    • Nếu toàn bộ symbol liên quan đến liên kết đều không được định nghĩa thì module sẽ không liên kết được, nhờ đó có thể phát hiện bug sớm hơn và ngăn các vấn đề vô tình phát sinh từ tên symbol
    • Các symbol liên quan đến liên kết nhưng chưa được định nghĩa thường cho thấy bug trong thời gian build hoặc lỗi cấu hình
    • Nếu hành vi cũ là chủ đích, có thể quay lại bằng RUSTFLAGS=-Clink-arg=--allow-undefined, hoặc dùng #[link(wasm_import_module = "env")] trong khối định nghĩa symbol ở mã nguồn
    • Thay đổi này được áp dụng trong Rust 1.96 sau thông báo trên blog trước đó

API được ổn định hóa và bản vá bảo mật

1 bình luận

 
Ý kiến trên Lobste.rs
  • Tôi cứ thấy mình muốn có assert_matches, nhưng mỗi lần lại phải cân nhắc giữa việc thêm một crate mới hay tự triển khai lại
    Vì vậy việc nó được đưa vào thư viện chuẩn là điều đáng mừng

    • Có lạ không khi thấy háo hức vì có thể xóa đi hàng trăm cặp ngoặc trong test? Tôi nghĩ là không hề
  • Tôi thích bước tiến hướng tới việc biến phạm vi thành kiểu Copy
    Thỉnh thoảng tôi lại ngạc nhiên vì phải clone một phạm vi, và điều này cũng hợp hơn với trực giác rằng 12..34 nên là dữ liệu nhỏ và có thể sao chép được
    Tuy vậy, nếu xuất hiện nhiều kiểu cùng tên thì tôi hơi lo VS Code lần tới khi tự thêm khai báo use sẽ lấy nhầm kiểu

    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.
    Hệ thống edition của Rust có vẻ là một ý tưởng khá hay

    • Theo tôi biết, nếu import bị mơ hồ thì code action của VS Code sẽ mở một menu thả xuống để chọn dùng cái nào
    • Tôi nghĩ bình thường cũng không cần import kiểu này quá thường xuyên
      Với đa số người dùng, lợi ích của kiểu mới là nhỏ nên cứ tiếp tục dùng kiểu cũ là được, rồi đến ranh giới edition tiếp theo thì kiểu mới sẽ tự động được dùng
      Có lẽ chủ yếu là các tác giả thư viện muốn hỗ trợ rõ ràng cả hai phiên bản mới phải import các kiểu này
  • 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.
    Điều này nghe hơi lạ
    Không biết sau này có định thay đổi không? Nó giống kiểu việc mà sau khi hệ sinh thái đã chuyển sang, ví dụ khoảng 3 năm sau, người ta sẽ muốn làm như một đợt dọn dẹp nhỏ

    • Edition rất hữu ích cho những việc như thế này
      Có thể thay đổi prelude mà không làm hỏng các dự án hiện có