#reference #deferred #pointers #lifetime #borrow #raw-pointers

无std 延迟引用

延迟引用实际上不是引用,它只是与它所指向位置的生存期相关的智能指针

2个版本

0.1.2 2021年4月5日
0.1.1 2021年4月4日
0.1.0 2021年4月3日

#377并发

MIT 许可证

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”中工作。这两个概念之间也存在一些相似之处:两者都是在编译时静态应用的,并且不会产生任何运行时开销。此外,在这两种方法中,实际引用只有在引用实际使用时(即解引用或借用一段时间)才会创建。

无运行时依赖

功能