Rust开发团队很高兴地宣布发布Rust的新版本1.32.0。 Rust是一种编程语言,使每个人都可以创建可靠且高效的软件。
如果您已经使用rustup
安装了rustup
版本的Rust,那么只需将Rust升级到rustup
版本,您只需执行以下操作:
$ rustup update stable
如果尚未安装rustup
,则可以从我们网站的相应页面进行安装 。 可以在GitHub上找到Rust 1.32.0的详细发行说明 。
rustup
说明: rustup
发布了一些新的rustup
版本! 要更新rustup
本身,请执行rustup self update
。
稳定版1.32.0中包含什么
Rust 1.32.0获得了一些改善生活的改进,更改了默认内存分配器,并使更多功能保持不变。 在下面阅读有关这些更改的信息,或在发行说明中查看更多信息。
DBG宏
让我们从改善生活开始。 您是否使用打印调试? 如果是这样,并且您想在处理代码时打印一些值,则必须这样做:
let x = 5; println!("{:?}", x);
这不是减慢开发速度的最大障碍,但仅调试x
值的输出就需要花费大量精力。 此外,此处未考虑上下文。 如果您有几个这样的println!
s,直到您自己向每个调用添加上下文信息之前,要确定输出所指的内容就变得很困难,这需要更多的工作。
为此,在Rust 1.32.0中, 我们添加了一个新的宏dbg! :
fn main() { let x = 5; dbg!(x); }
启动该程序后,您将看到:
[src/main.rs:4] x = 5
连同变量名及其值一起,将显示进行dbg!
调用的文件名和行号dbg!
。
另外, println!
打印到标准输出,因此最好使用eprintln!
打印到标准错误流。 宏dbg!
输出到stderr
,正确的是。
即使在困难的情况下也可以使用。 考虑一个析因实现的例子:
fn factorial(n: u32) -> u32 { if n <= 1 { n } else { n * factorial(n - 1) } }
为了对其进行调试,我们可以使用eprintln!
:
fn factorial(n: u32) -> u32 { eprintln!("n: {}", n); if n <= 1 { eprintln!("n <= 1"); n } else { let n = n * factorial(n - 1); eprintln!("n: {}", n); n } }
我们希望在每次迭代中输出n
并查看每个分支的上下文。 对于factorial(4)
它将输出:
n: 4 n: 3 n: 2 n: 1 n <= 1 n: 2 n: 6 n: 24
这是可以接受的,但不是特别好。 也许我们可以努力改善上下文信息的输出,以使结论更清晰。 但是,然后,我们将对调试代码进行改进,而不是调试我们的代码。
考虑使用dbg!
的相同示例dbg!
:
fn factorial(n: u32) -> u32 { if dbg!(n <= 1) { dbg!(1) } else { dbg!(n * factorial(n - 1)) } }
我们只是将宏与每个要输出的表达式包装在一起。 结果,我们得到:
[src/main.rs:3] n <= 1 = false [src/main.rs:3] n <= 1 = false [src/main.rs:3] n <= 1 = false [src/main.rs:3] n <= 1 = true [src/main.rs:4] 1 = 1 [src/main.rs:5] n * factorial(n - 1) = 2 [src/main.rs:5] n * factorial(n - 1) = 6 [src/main.rs:5] n * factorial(n - 1) = 24 [src/main.rs:11] factorial(4) = 24
由于宏是dbg!
返回调试值本身,与eprintln!
不同eprintln!
,它返回()
,那么我们不需要对代码的结构进行任何更改。 此外,我们得出了一个更有用的结论。
我们非常关注这样一个小的宏,因为我们希望它可以简化您的调试过程。 当然,我们还将继续致力于支持gdb
和Co。
jemalloc
删除jemalloc
从前,Rust具有类似于Erlang的大型运行时。 对他来说,选择jemalloc代替了系统分配器,因为它通常效率更高。 逐渐地,我们越来越多地摆脱了运行时,最后几乎删除了所有运行时,但保留了jemalloc。 我们没有选择自定义分配器的方法,因此我们不能完全删除jemalloc,以免伤害需要它的人。
另外,断言jemalloc
始终是默认jemalloc
的说法主要与UNIX世界有关,因为默认情况下仅在某些平台上才使用它。 特别是,Windows上MSVC的目标长期以来一直使用系统分配器。
最后,尽管jemalloc 通常具有良好的性能,但并非总是如此。 此外,它为每个可执行文件增加了约300 KB。 此外,我们在使用jemalloc时还积累了许多其他问题 。 通常,奇怪的是系统语言默认情况下不使用系统分配器。
由于这些原因, Rust 1.28提供了一种选择全局分配器的方法后 ,我们便开始计划切换到默认的系统分配器,并提供jemalloc
作为外部库。 在Rust 1.32中,我们终于完成了这项工作,现在默认情况下,您的程序将使用系统分配器。
如果要继续使用jemalloc,请使用jemallocator库 。 为此,请在Cargo.toml
指定:
jemallocator = "0.1.8"
在项目的根文件中:
#[global_allocator] static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
仅此而已! 如果不需要jemalloc,则不再需要使用它,但如果需要,则只需几行代码即可解决问题。
最终模块系统改进
在最后两个版本中,我们讨论了对模块系统的一些改进。 在1.32.0和2018版中,我们添加了最新更改。 它称为“统一路径” ,允许您以与以前无法正常工作的其他路径相同的方式使用导入路径。 例如:
enum Color { Red, Green, Blue } use Color::*;
由于use
的路径应该以super
, self
或crate
开头,因此该代码尚未进行过编译。 现在,由于编译器支持一致的路径,因此此代码可以正常工作并达到您期望的效果:导入上面定义的Color
枚举的变体。
此更改完成了我们对模块系统的修订。 我们希望您喜欢使用简化系统!
宏增强
Rust 1.32.0发布了一些宏增强功能。 首先,添加了一个新的文字片段说明符 :
macro_rules! m { ($lt:literal) => {}; } fn main() { m!("some string literal"); }
literal
片段映射到任何类型的文字:字符串,数字和字符。
在2018 macro_rules
您也可以使用macro_rules
?
:
macro_rules! bar { ($(a)?) => {} }
片段与?
零个或一个出现将被匹配,就像带有*
的片段已经匹配“零个或多个”出现以及带有+
的片段一个或多个出现一样。
稳定标准库
宏dbg!
,我们已经在上面进行了描述,它已经成为标准库的重要补充。 此外,使19个函数保持不变,并且所有数字基元类型都将转换函数转换为字节数组,反之亦然,并且具有指定的字节顺序。 有六个函数,名称分别为to_<endian>_bytes
和from_<endian>_bytes
,其中<endian>
是:
ne
本地顺序(本地字节序)le
从初中到高级(小端)- 从大到小的顺序(大端)
有关更多详细信息,请参见发行说明 。
货运增强
货物收到了用于货物检查命令的别名货物c ,现在允许在存储库URL中使用用户名 。
有关更多详细信息,请参见发行说明 。
开发人员1.32.0
很多人一起创建了Rust 1.32.0。 没有你们每个人,我们不可能完成工作。 谢谢你
译者:我特别感谢Rustycrate社区的成员以及@dashadee和ozkriff的个人翻译和校对工作。