Rust 1.40.0 已经正式发布。该版本的亮点包括有 #[non_exhaustive] 和 macros!() and #[attribute]s 的改进。
具体更新内容如下:
#[non_exhaustive] 结构,枚举和变体
当属性#[non_exhaustive]附加到struct或的变体时enum,它将防止定义它的板条箱外部的代码构造所述struct或变体。为了避免将来损坏,还防止其他包装箱在田地上进行彻底匹配。以下示例说明了beta取决于的错误alpha:
// alpha/lib.rs:
#[non_exhaustive]
struct Foo {
pub a: bool,
}
enum Bar {
#[non_exhaustive]
Variant { b: u8 }
}
fn make_foo() -> Foo { ... }
fn make_bar() -> Bar { ... }
// beta/lib.rs:
let x = Foo { a: true }; //~ ERROR
let Foo { a } = make_foo(); //~ ERROR
// `beta` will still compile when more fields are added.
let Foo { a, .. } = make_foo(); //~ OK
let x = Bar::Variant { b: 42 }; //~ ERROR
let Bar::Variant { b } = make_bar(); //~ ERROR
let Bar::Variant { b, .. } = make_bar(); //~ OK
// -- `beta` will still compile...
幕后发生的事情是,#[non_exhaustive] struct或的构造函数的可见性enum降低到pub(crate),从而阻止了在定义它的板条箱外部进行访问。
更重要的方面是,#[non_exhaustive]也可以附加到enum自身上。从标准库中获取的示例是Ordering:
#[non_exhaustive]
pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst }
#[non_exhaustive]在此上下文中的目的是确保可以随时间添加更多变体。这是通过防止其他包装箱从详尽模式实现match-ing上Ordering。也就是说,编译器将拒绝:
match ordering {
// This is an error, since if a new variant is added,
// this would suddenly break on an upgrade of the compiler.
Relaxed | Release | Acquire | AcqRel | SeqCst => {
/* logic */
}
}
取而代之的是,其他板条箱需要通过添加通配符来解决更多变体的可能性,例如_:
match ordering {
Relaxed | Release | Acquire | AcqRel | SeqCst => { /* ... */ }
// OK; if more variants are added, nothing will break.
_ => { /* logic */ }
}
有关该#[non_exhaustive]属性的更多详细信息,可参见稳定性报告。
Macro and attribute 的改进
例如,用户可以编写以下类型:Foo = expand_to_type!(bar); 其中 expand_to_type 将是一个 procedural macro。
包括有bang!() macros, 例如:
macro_rules! make_item { ($name:ident) => { fn $name(); } }
extern {
make_item!(alpha);
make_item!(beta);
}
Procedural macro attributes on items in extern { ... } blocks 现在也被支持:
extern "C" {
// Let's assume that this expands to `fn foo();`.
#[my_identity_macro]
fn foo();
}
目前,函数式(mac!())和属性(#[mac])macros 都可以生成macro_rules!项目。
也就是说,以下内容现在有效:
macro_rules! accept_meta { ($m:meta) => {} }
accept_meta!( my::path );
accept_meta!( my::path = "lit" );
accept_meta!( my::path ( a b c ) );
accept_meta!( my::path [ a b c ] );
accept_meta!( my::path { a b c } );
标准库中增加的 const fn
此版本中,以下函数成为const fn:
增加到标准库的函数
以下函数和宏已经稳定:
{f32,f64}::to_be_bytes,{f32,f64}::to_le_bytes,{f32,f64}::to_ne_bytes,{f32,f64}::from_be_bytes,{f32,f64}::from_le_bytes,和{f32,f64}::from_ne_bytes
详情可查看更新说明:
https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html
(文/开源中国)