Rust 团队很高兴地宣布 Rust 的新版本 1.38.0。Rust 是一种编程语言,它使每个人都能构建可靠且高效的软件。
如果您之前通过 rustup 安装了 Rust,那么获取 Rust 1.38.0 非常简单,只需执行以下命令:
$ rustup update stable
如果您还没有安装 rustup,可以从我们网站上的相应页面获取rustup
。
1.38.0 稳定版的新特性
此版本的主要亮点是流水线编译。
流水线编译
要编译一个 crate,编译器不需要完全构建依赖项。相反,它只需要它们的“元数据”(即类型列表、依赖项、导出项...)。此元数据在编译过程的早期生成。从 Rust 1.38.0 开始,Cargo 将利用这一点,在元数据准备就绪后立即开始构建依赖的 crate。
虽然此更改对单个 crate 的构建没有任何影响,但在测试期间,我们收到了报告,称某些 crate 图的优化、全新构建的编译速度提高了 10-20%。其他一些并没有太大的改进,并且加速效果取决于运行构建的硬件,因此实际效果可能会有所不同。无需更改代码即可从中受益。
mem::{uninitialized, zeroed}
的不正确使用
检测一些对 如先前宣布的那样,std::mem::uninitialized
本质上不可能安全使用。相反,应该使用 MaybeUninit<T>
。
我们尚未弃用 mem::uninitialized
;这将在未来的版本中完成。但是,从 1.38.0 开始,rustc
将为使用 mem::uninitialized
或 mem::zeroed
的一小部分不正确的初始化提供 lint。
对于某些类型(例如 &T
和 Box<T>
),包含全 0
位模式是未定义的行为,因为它们表示不能为 null
的类似指针的对象。因此,使用 mem::uninitialized
或 mem::zeroed
初始化这些类型之一是错误的,因此,新的 lint 将尝试在任何时候使用这些函数来初始化它们中的一个(无论是直接初始化还是作为更大的 struct
的成员)时发出警告。该检查是递归的,因此以下代码将发出警告:
struct Wrap<T>(T);
struct Outer(Wrap<Wrap<Wrap<Box<i32>>>>);
struct CannotBeZero {
outer: Outer,
foo: i32,
bar: f32
}
...
let bad_value: CannotBeZero = unsafe { std::mem::uninitialized() };
精明的读者可能会注意到,Rust 有更多不能为零的类型,尤其是 NonNull<T>
和 NonZero<T>
。目前,对于这些结构体使用 mem::uninitialized
或 mem::zeroed
进行初始化不会发出 lint 警告。
这些检查并不涵盖 mem::uninitialized
或 mem::zeroed
的所有不安全使用情况,它们仅仅有助于识别肯定是错误的代码。所有代码仍然应该改为使用 MaybeUninit
。
#[deprecated]
宏
#[deprecated]
属性最初在 Rust 1.9.0 中引入,允许 crate 作者通知其用户他们的 crate 的某个项已被弃用,并将在未来的版本中删除。Rust 1.38.0 扩展了此属性,允许将其应用于宏。
std::any::type_name
对于调试,有时获取类型的名称很有用。例如,在泛型代码中,您可能希望在运行时查看函数的类型参数实例化了哪些具体类型。现在可以使用 std::any::type_name
完成此操作。
fn gen_value<T: Default>() -> T {
println!("Initializing an instance of {}", std::any::type_name::<T>());
Default::default()
}
fn main() {
let _: i32 = gen_value();
let _: String = gen_value();
}
这将打印
Initializing an instance of i32
Initializing an instance of alloc::string::String
与所有仅用于调试的标准库函数一样,字符串的确切内容和格式不保证。返回的值只是对类型的尽力描述;多个类型可能共享相同的 type_name
值,并且该值可能会在未来的编译器版本中更改。
库的更改
slice::{concat, connect, join}
现在除了&T
之外,还接受&[T]
。*const T
和*mut T
现在实现marker::Unpin
。Arc<[T]>
和Rc<[T]>
现在实现FromIterator<T>
。iter::{StepBy, Peekable, Take}
现在实现DoubleEndedIterator
。
此外,以下函数已稳定:
<*const T>::cast
和<*mut T>::cast
Duration::as_secs_f32
和Duration::as_secs_f64
Duration::div_f32
和Duration::div_f64
Duration::from_secs_f32
和Duration::from_secs_f64
Duration::mul_f32
和Duration::mul_f64
- 欧几里得余数和除法运算 --
div_euclid
,rem_euclid
-- 适用于所有整数原始类型。还提供checked
、overflowing
和wrapping
版本。
其他更改
Rust 1.38 版本还有其他更改:请查看 Rust、Cargo 和 Clippy 中的更改。
更正
此帖子的先前版本错误地将这些函数标记为稳定。它们尚未稳定。Duration::div_duration_f32
和 Duration::div_duration_f64
。
1.38.0 的贡献者
许多人共同努力创建了 Rust 1.38.0。没有你们所有人,我们不可能做到这一点。谢谢!