rust - 为什么有时似乎允许在涉及 += 运算符的同一表达式中使用可变引用和不可变引用,有时则不允许?
问题描述
在下面的代码示例中,我试图以四种不同的方式通过对它的可变引用来增加a
结构的成员变量。X
在这里,编译器为由 表示的行给出以下错误B
:
error[E0502]: cannot borrow `*x` as immutable because it is also borrowed as mutable
--> src\main.rs:17:23
|
17 | *x.get_a_mut() += x.get_a(); //B DOESN'T COMPILE
| ------------------^--------
| || |
| || immutable borrow occurs here
| |mutable borrow occurs here
| mutable borrow later used here
如果在同一个表达式中使用可变引用和不可变引用是一个问题,a
为什么要编译?C
D
struct X {
a: i64,
}
impl X {
pub fn get_a_mut(&mut self) -> &mut i64 {
return &mut self.a;
}
pub fn get_a(&self) -> &i64 {
return &self.a;
}
}
fn my_fn(x: &mut X) {
*x.get_a_mut() += 5; //A
*x.get_a_mut() += x.get_a(); //B DOESN'T COMPILE
*x.get_a_mut() += 2 * x.get_a(); //C
*x.get_a_mut() = x.get_a() + x.get_a(); //D
}
fn main() {
let mut x = X { a: 50 };
my_fn(&mut x);
}
解决方案
根据+=
文档,您正在调用类似 in case 和类似in add_assign(lhs: &mut i64, rhs: &i64)
caseB
的东西,并且.add_assign(lhs: &mut i64, rhs: i64)
A
C
D
如果A
,rhs
是一个常数,不同于x.a
; 没问题。
如果C
,rhs
是临时的( 的结果2 * x.get_a()
)并且不需要保持引用就x.a
存在;没问题。
如果D
,rhs
是临时的( 的结果x.get_a() + x.get_a()
)并且不需要保持引用就x.a
存在;没问题。
但是说到case B
,rhs
就是参考了x.a
;那么此调用同时对同一数据 ( )使用可变 ( lhs
) 和不可变 ( ) 引用,这是被禁止的。rhs
x.a
你最终可以克隆rhs
: *x.get_a_mut() += x.get_a().clone()
。
推荐阅读
- php - 注意:使用 POST 的 php 中未定义的索引
- python - 将一些值作为变量传递
- java - 我应该使用哪个功能接口?
- javascript - 我可以使用 JavaScript 在 URL 中添加 /something 吗?
- r - gghighlight 打印 label_key
- javascript - 是否有一种有效且最佳的算法来上传图像或任何自动命名的文件?
- javascript - 使用波形器的进度条。js之类的音频标签有
- php - 我想使用 php 将照片从 android 上传到服务器,但我的 php 脚本生成错误
- java - 无法使用 paho-mqtt java 客户端代码连接到 aws-iot
- android - 如何使用 Google api 在服务器端验证 android 请求