#borrow #lifetime #macro

unborrow

宏,用于在参数中带有临时的 self 的 &mut self 方法调用中

4 个版本 (2 个破坏性更新)

使用旧的 Rust 2015

0.3.1 2017 年 1 月 20 日
0.3.0 2016 年 8 月 7 日
0.2.0 2016 年 7 月 7 日
0.1.0 2016 年 2 月 18 日

#2853Rust 模式

每月 40 次下载
用于 3 crates

MIT 许可证

7KB

这是一个微小的 Rust crate,它解决了借用检查器常见的烦恼。

有时,你尝试在对象上调用一个需要 &mut self 的方法,但你需要临时借用该对象来计算方法的参数。例如

let mut v = vec![1, 2, 3];
v.reserve(v.capacity()); // double the capacity of the vector

这段代码无法编译,因为出现了错误,说你不能同时以可变和不可变方式借用 v(对于 reserve)。但逻辑上,参数是在方法调用开始之前计算的,所以问题在哪里?不可变借用应该已经结束了!不幸的是,借用检查器并不这么认为,因为它的区域都是“词法”的——对应于源代码中的实际字符范围。我们可以通过像这样重写代码来修复错误

let mut v = vec![1, 2, 3];
let v_cap = v.capacity();
v.reserve(v_cap); // double the capacity of the vector

现在不可变借用在可变借用开始之前开始和结束,borrowck 很高兴。但这很繁琐。如果有一个宏能为我们做这件事就好了。

#[macro_use] extern crate unborrow;

let mut v = vec![1, 2, 3];
unborrow!(v.reserve(v.capacity()));

顺便说一下,如果你对 Rust 宏的卫生细节感兴趣,这个宏值得一看。"非词法生命周期"如果被添加到 Rust 语言中,这个问题可能会消失。

作为旁白,如果你对 Rust 宏的卫生细节感兴趣,这个宏值得一看。这个宏利用卫生来实现类似 "gensym" 的功能:为了在绑定中预计算一个函数的所有参数,我们需要为每个绑定预计算唯一的名称,这些名称不能与作用域中的任何其他变量冲突。如果你查看源代码的展开形式,看起来所有的绑定都被命名为 "arg"。但实际上,它们都是不同的,因为它们被标记了不同的卫生上下文。请参阅源代码以了解更多信息。

无运行时依赖