首页 > 解决方案 > Rust 中的所有输入都应该是可变的吗?

问题描述

我想输入一个值并将其分配给一个不可变的变量(应该是)。我怎样才能做到这一点?

目前,我正在这样做:

use std::io;

fn main() {
    let mut a = 0;
    let mut b = 1;
    let mut nth_term = String::new();
    io::stdin().read_line(&mut nth_term);
}

但是没有&mut,它会产生一个错误:types differ in mutability。如果我mut从声明中删除,我会收到如下错误:

error[E0308]: mismatched types
 --> src/main.rs:5:27
  |
5 |     io::stdin().read_line(&nth_term).expect("I/O error");
  |                           ^^^^^^^^^ types differ in mutability
  |
  = note: expected mutable reference `&mut std::string::String`
                     found reference `&std::string::String`

我怎么会有这样的东西:

let input_var = input(); // or some other function that inputs the value and directly assigns it.

我尝试阅读官方文档,前几章,但徒劳无功。

标签: rust

解决方案


Rust 中的可变性遵循名称,而不是值。因此,如果您有一个绑定到可变变量的值,并且您希望它是不可变的,那么您所要做的就是重新绑定它:

fn main() {
    let mut nth_term = String::new();
    io::stdin().read_line(&mut nth_term).expect("I/O error");
    let nth_term = nth_term;
    //  ^^^^^^^^-- no `mut`
}

将一个值重新绑定到具有不同可变性的相同名称是很常见的(请参阅Rust 中的 'let x = x' 做了什么?)。

您还可以将原始绑定放在块表达式中以最小化mut变量的范围:

fn main() {
    let nth_term = {
        let mut nth_term = String::new();
        io::stdin().read_line(&mut nth_term).expect("I/O error");
        nth_term
    };
}

BufRead::read_line以这种方式定义,因此您不需要String为每个读取的新行分配一个新的。该方法必须采取&mut,因为它可以增长字符串。尽管您可以使用 迭代输入行stdin().lines(),这确实会产生拥有String的 s,但没有标准 I/O 函数可以从标准输入读取单行并返回 a String(您可以简单地将其绑定到非mut变量)。当然,如果您发现自己经常这样做,您可以编写自己的函数,其中包含mut并返回,例如,一个io::Result<String>.


推荐阅读