我正在阅读chapter two of The Rust Programming Language,而我不明白的东西在这里引起了我的注意:
use std::io;
fn main() {
println!("Guess the number!");
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
println!("You guessed: {}", guess);
}
在代码行5上,它用let mut guess = String::new()
声明了一个可变变量,但是在下一行,read_line()
的参数也有一个mut
关键字。
如果首先将变量定义为可变的,那么为什么我们再次使用mut
而不是仅仅使用像这样的引用:
io::stdin().read_line(&guess).expect("Failed to read line");
如果为变量定义了类型,那么当我们使用引用时,默认情况下不应该存在类型(mut
)吗?
答案 0 :(得分:3)
因为您可以具有对可变变量的不可变引用或对可变变量的 mutable 引用。关键字mut
选择您要创建的参考类型。
let mut foo = 1;
example1(&foo); // May not modify `foo`
example2(&mut foo); // May modify `foo`
另请参阅:
答案 1 :(得分:3)
TL; DR:这是一项设计决策。 Rust编译器可以合理地推断出是否需要可变性。但是对于人类读者来说,这可能并不明显。
长篇故事
如果您看一下Rust的前辈,您会发现C ++中引用参数的使用并没有得到普遍认可。在C ++中:
foo.call(bar);
只有call
的定义会让您知道bar
是通过值,常量引用还是可变引用传递的。结果,Google Style Guide臭名昭著地要求为任何可修改的参数强制传递指针,以区分在调用方变量是否可以被调用修改,或者不是。
在设计Rust时,大量且刻意强调显式性。原因是代码读取比编写更多,因此应优化语法和语义以使其易于阅读和理解。
明确性和简洁性之间存在着紧张关系,因此明确性并不总是被人们所青睐,而是经常被优先考虑。
在可变引用的情况下,鉴于围绕借阅检查的规则以及可变借款对其的影响,首选明确性。
答案 2 :(得分:2)
请记住,默认情况下,Rust中的all都是不可变的,当您默认使用&
创建对某物的引用时,这将创建对不可变物的引用,至少对于该引用而言,允许值本身是可变,则值的实际可变状态无关紧要。
当您来自所有可变的语言时,这有点反常。您无需明确地告诉您某些东西是可变的,这是默认行为。当我们创建某事物的引用几乎是不存在时,需要明确地写出对它的引用是不可变的。
因此,要创建对可变变量的引用,必须显式使用&mut
。这是一条规则,编译器知道该值可以更改,并且可以为您完成该操作,但是Rust要求您显式编写它,就这么简单。