Rust 新版解读 | 1.68 | crates index 优化
Rust 1.68 官方 release doc: Announcing Rust 1.68.0 | Rust Blog
通过 rustup 安装的同学可以使用以下命令升级到 1.68 版本:
$ rustup update stable
Cargo 稀疏注册协议 (sparse protocol)
Cargo的“稀疏”注册协议已经稳定,它是用来读取注册在 crates.io 上的 crates 的索引的基础设施。以前的 git 协议(目前仍然是默认协议)会克隆一个包括所有 crates 的索引的仓库,但这已经开始遇到扩展限制问题,在更新该仓库时会出现明显的延迟。新协议应在访问 crates.io 时提供显着的性能提升,因为它只会下载有关实际用到的 crates 的索引。
要使用新的协议,需要设置环境变量 CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
,或者编辑 .cargo/config.toml
文件添加:
[registries.crates-io]
protocol = "sparse"
稀疏注册协议目前计划于 1.70.0 版本成为默认的协议。更多细节可以看官方博客的 announcement, RFC 2789, 当前 Cargo Book 的 文档
局部 Pin
构造
新增的 pin!
宏能够用 T
构造一个 Pin<&mut T>
,从而匿名捕获在局部状态内。这通常叫做 堆栈固定(stack-pinning),同时这个堆栈也可以被 async fn
或者 代码块 来捕获住。这个宏和一些 crates 里提供的(比如 tokio::pin!
)很像,但是标准库可以利用 Pin
的内部结构和 临时生命周期拓展(Temporary lifetime extension)来实现出更像表达式的宏。
#![allow(unused)] fn main() { /// Runs a future to completion. fn block_on<F: Future>(future: F) -> F::Output { let waker_that_unparks_thread = todo!(); let mut cx = Context::from_waker(&waker_that_unparks_thread); // Pin the future so it can be polled. let mut pinned_future = pin!(future); loop { match pinned_future.as_mut().poll(&mut cx) { Poll::Pending => thread::park(), Poll::Ready(result) => return result, } } } }
在这个例子中,原来的 future
将被移动到一个临时的局部区域,由新的 pinned_future
引用,类型为 Pin<&mut F>
,并且该 pin 受制于正常的借用检查器以确保它不会超过局部作用域。
alloc
默认错误处理
当 Rust 内存分配失败时,类似于 Box::new
和 Vec::push
的 API 无法反映出这个错误,从而采取了一些不同的措施。当使用 std
时,程序会打印 stderr
然后中止。从 Rust 1.68.0 开始,包含 std
的二进制程序仍然会继续这样,而不保护 std
只包含 alloc
的二进制程序会对内存分配错误调用 panic!
,如果需要可以再进一步通过 #[panic_handler]
来调整其行为。
未来,std
也可能会改成这样。
Others
其它更新细节,和稳定的API列表,参考原Blog