rust - 使用现有可变引用的嵌套方法调用

标签 rust reference borrow-checker borrowing

以下代码编译成功:

let mut v = vec![1];
let r = &mut v;
r.push(r.len());

虽然这个失败了:

let mut v = vec![1];
let r = &mut v;
r.push(v.len());

有错误:

error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
    |
    |     let r = &mut v;
    |             ------ mutable borrow occurs here
    |     r.push(v.len());
    |            ^ immutable borrow occurs here
    |     r.push(r.len());
    |     - mutable borrow later used here
  • 为什么第一个示例可以正确编译?是否因为外部和内部调用中使用了相同的引用:r?或者是因为它应用了 RFC 2025, Two-Phase Borrows ?还是别的什么?
  • 既然第一个示例成功了,为什么第二个示例会失败?为什么RFC 2025, Two-Phase Borrows在这里不适用吗?

我怀疑第一个示例中没有错误,因为编译器不会创建中间引用,并且它使用相同的引用:r,因此不会出现多次借用。 但是,如果是这样的话,为什么下面的代码无法编译

let mut v = vec![1];
let r = &mut v;
r.push({r.push(0);1});

最佳答案

在第二个示例中,当您尝试获取其长度时,v 仍然是可变借用的。 Vec::len 采用 &self,因此获取其长度意味着在已经可变借用的情况下进行不可变借用。

通过 r 访问 len() 仍然可以,因为您通过借用同一个借用,而不是再次借用。


请注意,即使第一个示例在 Rust 1.30 及更早版本(或 2015 版的 1.35)中也会失败,因为它依赖于 NLL(非词汇生命周期)。 NLL 的问题在于,它并不完全直观地知道什么是允许的。本质上,这意味着不超出数据词汇范围的借用是可以的,并且还有其他几个直观上正确的情况。你的第三个例子是 NLL 仍然不允许的情况之一。

关于rust - 使用现有可变引用的嵌套方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65477148/

相关文章:

rust - 在我克隆它之前,Vector 的生命周期不够长

java - 在 Java 应用程序中处理引用数据的类型安全方法

c++ - 友元函数返回对私有(private)数据成员的引用

rust - 错误[E0502] : cannot borrow `vector` as immutable because it is also borrowed as mutable

types - 使用相同的 Rust channel (mpsc) 发送不同的类型

struct - 升压凤凰: Binding to reference members of structures?

rust - 为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

rust - 有没有一种方法可以在Rust中使用avro-rs序列化JSON值?

rust - 迭代元组数组时出现错误 "no field ` n`"是什么意思?

rust - 不安全代码中可变引用的别名是否正确?