Rust 1.40.0版本:#[non_exhaustive],宏增强和其他增强

Rust团队很高兴地宣布发布新版本1.40.0。 Rust是一种编程语言,它使每个人都可以创建可靠而高效的软件。


如果您使用rustup安装了rustup版本的Rust,那么要升级到1.40.0版本,您只需要运行以下命令:


 $ rustup update stable 

如果尚未安装rustup ,则可以从我们网站的相应页面进行安装 ,以及在GitHub上查看详细的发行说明


稳定版1.40.0中包含什么


主要的创新是引入了属性#[non_exhaustive] ,对macros!()改进macros!()#[attribute] 。 最终,借款人的迁移分析器警告成为Rust 2015中的错误。有关更多信息,请参见发行说明。


#[non_exhaustive]结构,枚举和枚举选项


假设您是一个包含pub struct Fooalpha库的作者。 您想公开alpha::Foo结构的字段,但是不确定在将来的版本中是否必须向Foo添加更多字段。 出现了两难境地:要么将字段设置为私有,否则会带来不便,或者冒着使用户依赖字段的风险,然后在添加新字段时违反其代码。 Rust 1.40.0引入了一种使用#[non_exhaustive]解决问题的方法。


属性#[non_exhaustive]附加到枚举的结构或变量上,并防止字段的完全比较,防止在板条箱外部创建该结构或变量及其声明。 下面的示例演示依赖于alpha的beta板箱中的错误:


 // 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 }; //~  let Foo { a } = make_foo(); //~  let Foo { a, .. } = make_foo(); //~ OK // -- `beta`       . let x = Bar::Variant { a: 42 }; //~  let Bar::Variant { b } = make_bar(); //~  let Bar::Variant { b, .. } = make_bar(); //~ OK // -- `beta`    ... 

幕后发生了什么? #[non_exhaustive]结构或枚举选项的构造函数的可见性将降低为pub(crate) ,从而禁止在第三方板条箱中使用它们。


#[non_exhaustive]一个更重要的方面是属性可以附加到枚举本身。 这是从std::cmp::Ordering获取的代码:


 #[non_exhaustive] pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst } 

在这种情况下, #[non_exhaustive]保证将来有可能添加新选项。 这是通过禁止其他包装将详尽的图像匹配用于Ordering 。 编译器将拒绝以下内容:


 match ordering { Relaxed | Release | Acquire | AcqRel | SeqCst => { /* logic */ } //~^ ;      , //   ,        . } 

相反,其他软件包现在应该考虑使用新的枚举选项的可能性,例如,添加_通配符:


 match ordering { Relaxed | Release | Acquire | AcqRel | SeqCst => { /* logic */ } _ => { /* logic */ } // OK;     ,   . } 

有关属性#[non_exhaustive]详细信息,请参阅稳定性报告


宏和属性增强


在1.40.0中,我们对宏和属性进行了一些改进,包括:


  • 在类型上下文中 mac!()


    例如,您可以编写type Foo = expand_to_type!(bar); 其中expand_to_type将是程序宏。


  • extern { ... }块中的 extern { ... }


    该块包含make_item!()宏。 例如:


     macro_rules! make_item { ($name:ident) => { fn $name(); } } extern { make_item!(alpha); make_item!(beta); } 

    现在还支持extern { ... }块中元素的属性过程宏:


     extern "C" { #[my_identity_macro] //~  ,     `fn foo();`. fn foo(); } 

  • macro_rules! 程序宏中的项目。


    具有函数语法( mac!() )和属性( #[mac] )的macro_rules!现在可以生成macro_rules! 。 有关更多详细信息,请参见随附的稳定度报告。


  • $m:meta TokenStream $m:meta支持 TokenStream


    也就是说,以下代码是正确的:


     macro_rules! accept_meta { ($m:meta) => {} } accept_meta!( my::path ); accept_meta!( my::path = "lit" ); accept_meta!( my::path ( abc ) ); accept_meta!( my::path [ abc ] ); accept_meta!( my::path { abc } ); 


借用解析器的迁移警告在Rust 2015版中成为bug


在1.35.0版中, 我们报告NLLRust 1.31中 2018年版本的第一个发行版之后出现在Rust 2015版中。


正如我们所说,旧的借用分析器可能允许不安全的内存管理,而新的分析器(NLL借用检查器)可以解决这些缺点。 由于这些错误可能会破坏稳定的代码,因此我们决定逐步引入这些错误,检查旧的分析器是否允许程序的汇编,以及新的分析器是否将其阻止。 在这些情况下,错误将替换为警告。


先前版本的Rust 1.39.0在2018版中用代码错误替换了这些警告。 Rust 1.40.0将对2015版代码应用相同的更改,从而永久关闭这些安全漏洞。 随之, 编译器甚至从旧代码中清除了


如果您的项目不是由于上述更改引起的,或者您想了解更多信息,请阅读Niko Matsakis的帖子


标准库中的更多常量函数


从Rust 1.40.0开始,以下函数被标记为常量( const fn ):



标准库中的稳定功能


在Rust 1.40.0中稳定了以下功能和宏:



其他变化


语法货物包裹管理器Clippy分析器也进行了一些更改。


请阅读兼容性说明,以查看这些更改是否影响您。


成员1.40.0


很多人一起创建了Rust 1.40.0。 没有你们大家,我们不可能做到这一点, 谢谢


来自翻译


如果您对Rust语言有任何疑问,他们将可以在俄语电报聊天对新手进行的类似聊天中为您提供帮助。


本文由andreevlexblandgerfunkillHippolotP0luninPsyHaSTeLooMaclin共同翻译。

Source: https://habr.com/ru/post/zh-CN481070/


All Articles