为了账号安全,请及时绑定邮箱和手机立即绑定

无法借用不可变,因为它在函数参数中也借来可变

无法借用不可变,因为它在函数参数中也借来可变

Git
交互式爱情 2019-11-04 10:20:09
这是怎么回事(操场)?struct Number {    num: i32}impl Number {    fn set(&mut self, new_num: i32) {        self.num = new_num;    }    fn get(&self) -> i32 {        self.num    }}fn main() {    let mut n = Number{ num: 0 };    n.set(n.get() + 1);}给出此错误:error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable  --> <anon>:17:11   |17 |     n.set(n.get() + 1);   |     -     ^          - mutable borrow ends here   |     |     |   |     |     immutable borrow occurs here   |     mutable borrow occurs here但是,如果您只是简单地将代码更改为此:fn main() {    let mut n = Number{ num: 0 };    let tmp = n.get() + 1;    n.set(tmp);}对我来说,这些看起来完全等效-我的意思是,我希望前者在编译时会转换为后者。Rust不会在评估下一级函数调用之前评估所有函数参数吗?
查看完整描述

1 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

这行:


n.set(n.get() + 1);

被减为


Number::set(&mut n, n.get() + 1);

现在,错误消息可能会更加清楚:


error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable

  --> <anon>:18:25

   |

18 |     Number::set(&mut n, n.get() + 1);

   |                      -  ^          - mutable borrow ends here

   |                      |  |

   |                      |  immutable borrow occurs here

   |                      mutable borrow occurs here

当Rust从左到右评估参数时,该代码与此等效:


let arg1 = &mut n;

let arg2 = n.get() + 1;

Number::set(arg1, arg2);

现在应该很明显出了什么问题。交换前两行即可解决此问题,但Rust不会进行这种控制流分析。


它最初是作为Bug#6268创建的,现在已集成到RFC 2094(非词法生存期)中。如果您使用Rust 2018,则会自动启用NLL,并且您的代码现在将编译而不会出现错误。


查看完整回答
反对 回复 2019-11-04
  • 1 回答
  • 0 关注
  • 829 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信