为什么在引用可变变量时重新声明可变性?

时间:2018-10-08 22:19:08

标签: rust

我正在阅读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)吗?

3 个答案:

答案 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要求您显式编写它,就这么简单。