2个版本
0.1.2 | 2021年4月5日 |
---|---|
0.1.1 | 2021年4月4日 |
0.1.0 |
|
#377 在 并发
140KB
1.5K SLoC
延迟引用
此crate可以帮助创建对变量内容的多个可变引用,而不会触发未定义行为。Rust借用规则规定,即使在可变引用未被使用的情况下,创建对同一区域的多个可变引用也是未定义行为。然而,如果程序员知道两个可变引用不会重叠,这种限制可能有些过于严格。使用原始指针,今天已经可以通过绕过Rust借用规则来工作,但这需要像魔法师一样的技能和对处理原始指针的深入了解,而且这比使用Rust引用更容易出错。随着Rust 2018版本的引入,引用的易用性已经显著提高,但仍有一些特殊情况,程序员希望有一种方法可以创建非重叠的可变引用到同一位置(例如,切片或数组的非重叠索引),而无需手动管理原始指针。为了帮助解决这个问题,此crate引入了“延迟引用”的概念1。延迟引用几乎与常规引用完全相同(例如,&T
或&mut T
),但它与常规引用有以下不同之处
- 延迟引用实际上不是引用,它只是与它所指向位置的生存期相关的智能指针(常规原始指针始终具有静态生存期,因此如果它所指向的位置被移动或丢弃,它可能成为悬垂指针)。
- 可以保留多个延迟可变引用(只要这些引用没有以创建一个可变引用与另一个(解)引用之间的重叠的方式解引用)。
入门
如果您使用的是nightly Rust,请将以下依赖项添加到您的Cargo.toml
[dependencies]
deferred-reference = { version = "0.1.2" }
这个crate使用了一些不稳定的特性,但也可以在功能较少的稳定Rust上运行。要在稳定Rust中使用这个crate,您需要使用default-features
标志禁用不稳定的新特性,如下所示:
[dependencies]
deferred-reference = { version = "0.1.2", default-features = false }
请参阅此crate的文档以获取如何开始的一些具体代码示例。
#![no_std]
环境
此crate完全使用#![no_std]
,并且不依赖于alloc
crate。无需配置任何额外的Cargo.toml
功能来支持#![no_std]
环境。此crate也没有在Cargo.toml
中声明任何依赖。
Miri测试
此crate使用Miri通过-Zmiri-track-raw-pointers
标志进行了广泛的测试
$ MIRIFLAGS="-Zmiri-track-raw-pointers" cargo miri test
Miri遵循Stacked Borrows模型(由Ralf Jung等人提出),此crate也是如此。如果您在此crate中发现任何违反此模型的情况,请随时在Github上提交问题!
许可证
本项目采用MIT许可证。请参阅本项目根目录下的LICENSE.md
文件以获取完整的许可证文本。
贡献
如果您遇到问题或提出功能请求,建议您在Github上提交问题。目前,此项目还不接受拉取请求。请稍后再查看!
脚注
[1]: “延迟引用”的概念受到Chris Fallin所著的“Deferred Borrows”概念的启发。然而,这两个概念并不完全相同。它们的不同之处在于,延迟借用将Rust类型系统(称为静态路径相关类型)扩展到(),其实现旨在位于Rust编译器中,而延迟引用则是在Rust代码中实现的,而Rust代码今天已经可以使用其现有的类型系统。这里做出的权衡是,这需要尽可能少地使用具有延迟引用的unsafe
代码块,而如果这些在Rust编译器中实现,则延迟借用将完全在“安全Rust”中工作。这两个概念之间也存在一些相似之处:两者都是在编译时静态应用的,并且不会产生任何运行时开销。此外,在这两种方法中,实际引用只有在引用实际使用时(即解引用或借用一段时间)才会创建。