Rust 1.35.0版本:功能特性的实现和其他创新

在此,我向大家介绍了大家最喜欢的编程语言Rust的新版本的出版物翻译。


引言


Rust编程语言团队很高兴地宣布一个新版本1.35.0。 Rust是一种编程语言,它使每个人都可以开发可靠且快速的软件。


如果您使用rustup安装了rustup版本的Rust,那么获取当前版本将不会很困难:


 $ rustup update stable 

如果您仍然没有rustup ,则可以从我们网站上的相应页面获取它 。 可以在GitHub上获得此版本的详细评论


稳定版包含哪些内容?


此版本的主要创新包括分别在Box<dyn FnOnce>Box<dyn FnMut>Box<dyn Fn>结构上实现FnOnce, FnMutFn FnMut


以及内联函数(闭包)可以转换为不安全的函数指针。 宏dbg! 现在可以在不指定参数的情况下调用Rust 1.32.0中引入的功能。


此外,此版本引入了标准库的许多稳定功能。 以下是最重要的,但可以其中一些进行详细分析


Fn*Box<dyn Fn*>


在Rust 1.35.0中, FnMutBox<dyn FnOnce>Box<dyn FnMut>Box<dyn Fn> FnMut 实现 FnOnceFnMutFn FnMut


过去,如果要调用封装在Box<T>的函数,则必须使用FnBox ,因为Box<dyn FnOnce>对象等未实现相应的Fn*特征。 它还阻止了Box<T>的封装函数转移到等待Fn特征实现器的代码(建议创建临时内联函数)。


这是由于编译器无法检测到此类实现而引起的。 通过引入unsized_locals修复了此缺陷。


但是,现在,即使在希望实现功能特征的地方,也可以使用Box<T>封装的功能。 例如,下面的代码编译没有错误:


 fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> { vec![1, 2, 3, 4].into_iter().map(x).collect() } 

Box<dyn FnOnce>可以调用而不必大惊小怪:


 fn foo(x: Box<dyn FnOnce()>) { x() } 

转换为不安全的指针


Rust 1.19.0时代起,将不捕获环境的嵌入式函数转换为函数指针成为可能。 例如,您可以编写:


 fn twice(x: u8, f: fn(u8) -> u8) -> u8 { f(f(x)) } fn main() { assert_eq!(42, twice(0, |x| x + 21)); } 

但不幸的是,此功能尚未扩展为不安全的函数指针。 此版本引入了上述更改:


 ///  ,   `unsafe fn`. unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) { f() } fn main() { // :     //       //  unsafe { call_unsafe_fn_ptr(|| { dbg!(); }); } } 

调用dbg!()无参数


由于大量的println!电话println! 作为集体服务器场调试器, Rust 1.32.0中引入了dbg!dbg! 。 回想一下,此宏使您可以使用上下文快速捕获特定表达式的结果:


 fn main() { let mut x = 0; if dbg!(x == 1) { x += 1; } dbg!(x); } 

上面的代码行将分别将表达式x == 1x的结果打印到终端:


 [src/main.rs:4] x == 1 = false [src/main.rs:8] x = 0 

如上一节所述,在其中可以调用高阶函数call_unsafe_fn_ptr情况下,也可以在不指定参数的情况下调用dbg!() 。 这对于发现选定的程序分支非常有用:


 fn main() { let condition = true; if condition { dbg!(); // [src/main.rs:5] } } 

稳定标准库


在Rust 1.35.0中,标准库的许多组件已稳定。 除此之外,还引入了一些实现,您可以在此处阅读有关实现。


将浮点数的符号复制到另一个数字


在此发行版中,新的copysign方法已添加到浮点基元(更具体地说, f32f64 ):



就像建议的方法名称一样,您可以使用它们将一个数字的符号复制到另一个:


 fn main() { assert_eq!(3.5_f32.copysign(-0.42), -3.5); } 

检查Range是否包含特定值


Rust 1.35.0在Range*结构上获得了一些新方法:



使用这些方法,您可以轻松地检查某个值是否在范围内。 例如,您可以编写:


 fn main() { if (0..=10).contains(&5) { println!("5    [0; 10]."); } } 

翻译(映射)并拆分借用的RefCell


随着Rust 1.35.0的到来,您可以将借用的RefCell值转换并拆分为一组借用的值,并分为借用数据的不同组成部分:



通过内联函数RefCell


此版本引入了在RefCell结构上声明的便捷的replace_with方法:



散列指针或链接到


此版本引入了ptr::hash函数,该函数使用原始指针进行哈希处理。 使用ptr::hash可以防止对指定或引用值而不是地址本身进行哈希处理。


复制内容Option<&T>


从Rust 1.0.0开始, Option<&T>Option<&mut T>上的Option::cloned方法使存在的内容( Some(_) )的克隆成为可能。 但是,克隆有时可能是一项昂贵的操作,并且opt.cloned()方法没有描述任何提示。


此版本贡献了:



opt.copied()的功能与opt.copied()相同。 但是,上述方法要求条件T: Copy ,条件失败将导致编译错误。


短时变化


Clippy是一种可以捕获常见缺陷以提高代码质量的工具,它已经获得了drop_bounds 。 当广义函数要求条件T: Drop满足时,它起作用T: Drop


 fn foo<T: Drop>(x: T) {} 

这通常是一个错误,因为基元不实现Drop 。 而且, T: Drop不覆盖诸如String类的类型,它们没有破坏性的行为,而是内联类型的结果(如Vec<u8> )。


除了drop_bounds ,此版本drop_bounds redundant_closure 拆分redundant_closureredundant_closure_for_method_calls


此处阅读Clippy的详细版本。


货物变化


此处提供有关货物更改的详细说明。


成员1.35.0


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


来自翻译


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

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


All Articles