rust - 所有权转移后的变异变量

标签 rust transfer ownership

我知道如何使代码工作我只是想知道为什么会这样。
假设以下程序:

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`.
我知道只需添加 mutname 旁边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 &Tmut &mut T )提供了将此引用重新分配给另一个值的能力(被认为是可变的或不可变的,取决于正确的 mut )。
如果您熟悉 C 或 C++,这类似于使用 const声明指针时在星号之前或之后(或两边)。
简而言之,使用 mut on a variable 是相对于您在算法中修改存储在此变量中的内容的意图,但它不是此变量内容的属性。

关于rust - 所有权转移后的变异变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66430535/

相关文章:

html - 如何使用 html5 和文件 API 将单个文件从一个客户端浏览器发送到另一个客户端浏览器而不将其保存在服务器 (node.js) 上

java - 无法使用 JAVA 中的网络将文件从一台电脑传输到另一台电脑

generics - 编译器如何推断Box正在借用其内容借来的那个?

pointers - Golang 复制包含指针的结构

c++ - 采用预创建值的所有者对象?错误的设计?

rust - 值在明确的生命周期内不会存在足够长的时间,但在省略时会存在足够长的时间

concurrency - 如何使用 Condvar 和 Mutex 监控变化

rust - 如何习惯性地将Option <T>转换为Result <T,()>?

rust - 尝试使用 Diesel 查询时溢出评估需求 `_: Sized`

ios - 如何获取用户输入的数据并将其保存以便稍后在另一个 View 中显示?