cha*_*its 1 lifetime rust borrow-checker
我遇到一些Rust代码的问题,我被允许在某些条件下(第一个令人困惑的部分)不止一次地借用一些东西,而不是其他东西.
我写了下面的例子来说明:( 游乐场)
struct NoLifetime {}
struct WithLifetime <'a> {
pub field: &'a i32
}
fn main() {
let mut some_val = NoLifetime {};
borrow_mut_function(&mut some_val);
borrow_mut_function(&mut some_val); // Borrowing as mutable for the second time.
let num = 5;
let mut life_val = WithLifetime { field: &num };
borrow_lifetime(&mut life_val);
borrow_lifetime(&mut life_val); // Borrowing as mutable for the second time.
let num_again = borrow_lifetime(&mut life_val); // Borrow, assign lifetime result
borrow_lifetime(&mut life_val); // Compiler: cannot borrow `life_val` as mutable more than once
}
fn borrow_mut_function(val_in: &mut NoLifetime) -> String {
"abc".to_string()
}
fn borrow_lifetime<'a>(val_in: &'a mut WithLifetime) -> &'a i32 {
val_in.field
}
Run Code Online (Sandbox Code Playgroud)
如果你看到,我可以借两个some_val,并且life_val不止一次可变.但是,在分配了返回值之后borrow_lifetime,我再也无法借用了.
我的问题如下:
borrow_函数时,我都是可变的.任何帮助,将不胜感激.我想这里发生的事情是,我误解了"借用可变性"的真正含义,以及何时确定某些东西被借用为可变的东西.
克里斯已经给出了它的要点,但我认为值得进一步解释.
有2点的方式来鲁斯特转移所有权:
与许多其他语言一样,Rust使用一堆词法范围模拟时间传递.因此,现在,借用从创建它的地方开始,并延伸到其范围的末尾.
因此,借款何时结束的问题类似于询问借款的创造范围.
让我们用编号行来检查你的例子:
fn main() {
let mut some_val = NoLifetime {}; // 1
borrow_mut_function(&mut some_val); // 2
borrow_mut_function(&mut some_val); // 3
//
let num = 5; // 4
let mut life_val = WithLifetime { field: &num }; // 5
borrow_lifetime(&mut life_val); // 6
borrow_lifetime(&mut life_val); // 7
//
let num_again = borrow_lifetime(&mut life_val); // 8
borrow_lifetime(&mut life_val); // 9
}
Run Code Online (Sandbox Code Playgroud)
调用函数时,借用参数:
那么,让我们来看看:
在第(2)和(3)行中,您调用borrow_mut_function哪个返回String:结果不与参数共享任何生命周期,因此该参数仅在函数调用的生命周期内被借用.
在第(6)和(7)行调用borrow_lifetime,它返回一个&'a i32:结果与参数共享一个生命周期,因此参数被借用直到结果范围的结尾...这是因为结果未被使用.
在第(8)行,你调用borrow_lifetime哪个返回a &'a i32并将结果赋值给num_again:结果与参数共享一个生命周期,因此参数被借用到范围的结尾num_again.
在第(9)行,你打电话borrow_lifetime但它的论据仍然借用,num_again所以这个电话是非法的.
就是这样,这就是Rust今天的工作方式.
在未来,有一个非词汇借阅的呼吁.也就是说,编译器会意识到:
num_again 从未使用过num_again没有特定的析构函数(没有Drop实现)因此可以决定其借款的结束时间早于词汇范围的结束.
这是关于借款的范围,以及你是否保持借款.在大多数上述调用中,some_val在函数调用期间借用,但在函数返回后返回.
在例外情况下:
let num_again = borrow_lifetime(&mut life_val); //Borrow, assign lifetime result
Run Code Online (Sandbox Code Playgroud)
您life_val在调用期间借用borrow_lifetime,但由于返回值与参数('a)具有相同的生命周期,因此借用范围将扩展为包括生命周期num_again,即直到函数结束.再借life_val一次是不安全的,因为num_again它仍然是对它的参考.
| 归档时间: |
|
| 查看次数: |
260 次 |
| 最近记录: |