我知道如何使代码工作我只是想知道为什么会这样。
假设以下程序:
fn dummy(name: String) {
let last_name = " Wang".to_string();
name.push_str(&last_name);
println!("Hello, {}", name);
}
fn main() {
println!("What is your name?");
let mut name = String::new();
std::io::stdin().read_line(&mut name).expect("Couldn't read input!");
name.pop();
dummy(name);
}
尝试编译时出现以下错误:error[E0596]: cannot borrow `name` as mutable, as it is not declared as mutable
--> print.rs:3:5
|
1 | fn dummy(name: String) {
| ---- help: consider changing this to be mutable: `mut name`
2 | let last_name = " Wang".to_string();
3 | name.push_str(&last_name);
| ^^^^ cannot borrow as mutable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.
我知道只需添加 mut
在 name
旁边in function definition 解决了这个问题,但是为什么要在函数定义中声明它为可变变量 name
之前在 main
中被定义为可变的功能?编译器不应该知道变量之前是可变的,为什么它不能随之转移所有权和可变的“属性”?
也许这是个愚蠢的问题,但我是 Rust 的新手。如果它表现得如此,它会引入一些新问题/错误的可能性吗?如果是的话,你能举一些例子吗?
最佳答案
name
的事实作为参数传递只是一个细节。
在这个简化的例子中,我们可以重现相同的效果。
fn main() {
let mut name1 = "first".to_owned();
name1.push_str(" second");
let mut name2 = name1;
name2.push_str(" third");
let name3 = name2;
// name3.push_str(" fourth"); // rejected
let mut name4 = name3;
name4.push_str(" fifth");
println!("{}", name4);
}
字符串的所有权从 name1
更改至name2
, name3
然后 name4
并且这些变量(绑定(bind))中的每一个都决定(有或没有 mut
)它现在是唯一所有者的字符串是否可以突变。初始化函数的参数类似于初始化另一个变量(借用/所有权转移/复制...),一旦进入函数,参数就被视为任何其他局部变量,在这种情况下可能是可变的或不可变的。
如果您打算修改此参数,您可以使用
mut
声明它。或将其转移到另一个用 mut
声明的局部变量.请注意,我们正在处理 值 在这里,不是引用。
当然,你不能初始化
&mut T
来自 &T
.但是在前面加上
mut
在引用上(如 mut &T
或 mut &mut T
)提供了将此引用重新分配给另一个值的能力(被认为是可变的或不可变的,取决于正确的 mut
)。如果您熟悉 C 或 C++,这类似于使用
const
声明指针时在星号之前或之后(或两边)。简而言之,使用
mut
on a variable 是相对于您在算法中修改存储在此变量中的内容的意图,但它不是此变量内容的属性。
关于rust - 所有权转移后的变异变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66430535/