Rust中将变量所有权转移给函数后为何无法直接获得修改权限?
报错的根本原因
Rust中值的可修改权限,不仅和所有权相关,还和你把值绑定到的变量是否声明为mut直接相关:
- 你在原
main函数中声明的是let mut foo = String::from("Hello"),把String值绑定到了可变变量foo上,所以你拥有所有权的同时,有权修改值,自然可以取&mut引用传给write_foo。 - 你最初写的
move_foo函数参数是foo: String,这里虽然你拿到了String值的所有权,但参数foo是不可变绑定,相当于你把移动进来的值绑定到了一个不可变的局部变量上,自然没有权限取可变引用,编译器就会报错。
你后续把参数改成mut foo: String的修复方案是完全正确的:这个声明相当于告诉编译器,你把移动进函数的String值绑定到可变的局部变量foo上,你拥有完整的修改权限,自然可以正常取&mut引用。
关于你提到的作用域变量状态的补充说明
你理解的owned/mutable/readable三种状态基本正确,需要补充的是:owned状态默认仅代表你拥有值的完全控制权,能不能进入mutable可修改状态,还需要你把值绑定到mut声明的变量上才可以。你可以自由选择把所有权绑定到可变或不可变变量:如果绑定到不可变变量,那你哪怕有所有权也只能读,不能修改。
举个简单的例子,哪怕在同一个作用域下,下面的代码也会报错:
fn main() { // 没有mut声明,不可变绑定 let foo = String::from("Hello"); // 报错:cannot borrow `foo` as mutable, as it is not declared as mutable foo.push_str(" World"); }
你函数传参的逻辑和上面的例子完全一致:移动所有权只是把值传进了函数,但是绑定的变量是否可变是由函数参数的声明决定的。
内容的提问来源于stack exchange,提问作者David Alsh
相关产品推荐
相关产品推荐

