Rust 团队很高兴宣布 Rust 的新版本 1.34.0。Rust 是一种编程语言,它赋予每个人构建可靠高效软件的能力。
如果您之前通过 rustup 安装了 Rust,获取 Rust 1.34.0 就像
$ rustup update stable
如果您还没有,您可以从我们网站上的相应页面 获取 rustup
。
1.34.0 稳定版中的内容
此版本中最大的功能是引入了替代 cargo
注册表。该版本还包括对文档测试中 ?
的支持,对 #[attribute(..)]
的一些改进,以及 TryFrom
的稳定化。继续阅读以了解一些亮点,或查看 详细的发布说明 以获取更多信息。
cargo
注册表
替代 从 1.0 之前开始,Rust 就有一个公共的板条箱注册表,crates.io。人们使用 cargo publish
发布板条箱,并且很容易在 Cargo.toml
的 [dependencies]
部分中包含这些板条箱。
但是,并非每个人都希望将他们的板条箱发布到 crates.io。维护专有/闭源代码的人无法使用 crates.io,而是被迫使用 git
或 path
依赖项。这对于小型项目通常是可以的,但是如果您在一个大型组织中有很多闭源板条箱,您将失去 crates.io 提供的版本控制支持的优势。
通过此版本,Cargo 获得了对替代注册表的支持。这些注册表与 crates.io 共存,因此您可以编写依赖于来自 crates.io 和自定义注册表的板条箱的软件。但是,crates.io 上的板条箱不能依赖于外部注册表。
要使用替代注册表,您必须将这些行添加到您的 .cargo/config
中。此文件可以在您的主目录 (~/.cargo/config
) 中,也可以相对于包目录。
[registries]
my-registry = { index = "https://my-intranet:8080/git/index" }
依赖于来自替代注册表的板条箱很容易。在 Cargo.toml
中指定依赖项时,使用 registry
键让 Cargo 知道您希望从替代注册表中获取板条箱
[dependencies]
other-crate = { version = "1.0", registry = "my-registry" }
作为板条箱作者,如果您希望将您的板条箱发布到替代注册表,您首先需要使用 cargo login
命令将身份验证令牌保存到 ~/.cargo/credentials
中
cargo login --registry=my-registry
然后,您可以使用 --registry
标志来指示在发布时使用哪个注册表
cargo publish --registry=my-registry
有关于如何运行您自己的注册表的 文档。
?
文档测试中的 RFC 1937 提出在 fn main()
、#[test]
函数和 doctests 中添加对使用 ?
运算符的支持,允许它们返回 Option<T>
或 Result<T, E>
,错误值在 fn main()
的情况下导致非零退出代码,在测试的情况下导致测试失败。
fn main()
和 #[test]
中的支持是在 很多版本之前 实现的。但是,文档测试中的支持仅限于具有显式 fn main()
的 doctests。
在此版本中,已添加对 doctests 中 ?
的完全支持。现在,您可以在您的文档测试中编写以下内容
/// ```rust
/// use std::io;
/// let mut input = String::new();
/// io::stdin().read_line(&mut input)?;
/// # Ok::<(), io::Error>(())
/// ```
fn my_func() {}
您仍然必须在文档测试的底部指定正在使用的错误类型。
自定义属性接受任意标记流
过程宏 在 Rust 中可以定义它们消耗的自定义属性。到目前为止,此类属性仅限于根据特定语法作为路径和文字的树,例如
#[foo(bar)]
#[foo = "bar"]
#[foo = 0]
#[foo(bar = true)]
#[foo(bar, baz(quux, foo = "bar"))]
与过程宏不同,这些辅助属性不能接受分隔符中的任意标记流,因此您不能编写 #[range(0..10)]
或 #[bound(T: MyTrait)]
。过程宏板条箱将改为使用字符串来指定此类语法,例如 #[range("0..10")]
通过此 Rust 版本,自定义属性 #[attr($tokens)]
现在接受 $tokens
中的任意标记流,使其与宏相当。如果您是过程宏板条箱的作者,请检查您的自定义属性是否在其语法中包含不必要的字符串,以及它们是否可以使用标记流更好地表达。
TryFrom
和 TryInto
TryFrom
和 TryInto
特性已稳定,以允许错误类型转换。
例如,整数类型上的 from_be_bytes
和相关方法接受数组,但数据通常通过切片读取。在切片和数组之间进行转换手动操作很繁琐。使用新的特性,可以使用 .try_into()
内联完成。
let num = u32::from_be_bytes(slice.try_into()?);
对于不会失败的转换,例如 u8
到 u32
,添加了 Infallible
类型。这也允许对所有现有的 From
实现进行 TryFrom
的通用实现。将来,我们希望将 Infallible
转换为 !
(永不) 类型 的别名。
fn before_exec
已弃用,取而代之的是 unsafe fn pre_exec
在类 Unix 系统上,函数 CommandExt::before_exec
允许您安排在调用 exec
之前运行的闭包。
提供的闭包将在分叉后在子进程的上下文中运行。这意味着资源(如文件描述符和内存映射区域)可能会被复制。换句话说,您现在可以将非 Copy
类型的值的副本复制到不同的进程中,同时保留父进程中的原始副本。这使得 有可能 导致未定义的行为并破坏 假设不复制的库。
因此,函数 before_exec
应该被标记为 unsafe
。在此版本的 Rust 中,我们已弃用 fn before_exec
,取而代之的是 unsafe fn pre_exec
。在调用 CommandExt::pre_exec
时,您有责任确保闭包不会通过对这些副本的无效使用来违反库不变式。如果您提供的库与 before_exec
处于类似情况,请考虑弃用并提供 unsafe
替代方案。
库稳定化
在 1.34.0 中,稳定的原子整数类型的集合已扩展,现在提供从 8 (AtomicU8
) 到 64 位的有符号和无符号变体。
以前,非零无符号整数类型,例如 NonZeroU8
,已稳定。这使 Option<NonZeroU8>
的大小与 u8
相同。通过此 Rust 版本,有符号版本,例如 NonZeroI8
,已稳定。
函数 iter::from_fn
和 iter::successors
已稳定。前者允许您从 FnMut() -> Option<T>
构造迭代器。要从向量中迭代地弹出元素,您现在可以编写 from_fn(|| vec.pop())
。同时,后者创建一个新的迭代器,其中每个后续项都是根据前一个项计算的。
此外,这些 API 已稳定
- Any::type_id
- Error::type_id
- slice::sort_by_cached_key
- str::escape_debug
- str::escape_default
- str::escape_unicode
- str::split_ascii_whitespace
- Instant::checked_add
- Instant::checked_sub
- SystemTime::checked_add
- SystemTime::checked_sub
查看 详细的发布说明 以获取更多详细信息。