rustc 关于从未读过的值的误报警告?

rustc false positive warning about value never read?

关注 this article 关于用 Rust 编写 shell。编译器输出有关变量从未被读取的警告。

use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::process::Command;
use std::path::Path;

 fn main(){
    let mut input = String::new();

    loop {
            print!("> ");
            stdout().flush().unwrap();
//              input = String::from("");  //  **<===== HERE**
            stdin().read_line(&mut input).unwrap();
            let mut parts = input.trim().split_whitespace();
            let command = parts.next().unwrap();
            let args = parts;
            match command {
                "cd" => {
                    let new_dir = args.peekable().peek().map_or("/", |x| *x);
                    let root = Path::new(new_dir);
                    if let Err(e) = std::env::set_current_dir(&root) {
                        eprintln!("{}", e);
                    }
                },
                "exit" => return,
                command => {
                    let child = Command::new(command)
                        .args(args)
                        .spawn();
                    // gracefully handle malformed user input
                    match child {
                        Ok(mut child) => { child.wait().unwrap(); },
                        Err(e) => eprintln!("{}", e),
                    };
               }
           }
    }
}

但是,注释掉这一行会导致程序出错:这是注释前后的行为:

usn@DESKTOP:~/bqy/rust/p2$ cargo run
warning: value assigned to `input` is never read
 --> src/main.rs:8:10
  |
8 |     let mut input = String::new();
  |             ^^^^^
  |
  = note: `#[warn(unused_assignments)]` on by default
  = help: maybe it is overwritten before being read?

    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target/debug/p2`
> ls
Cargo.lock  Cargo.toml  src  target
> ls
Cargo.lock  Cargo.toml  src  target
> exit
usn@DESKTOP:~/bqy/rust/p2$ vi src/main.rs
usn@DESKTOP:~/bqy/rust/p2$ cargo run
   Compiling p2 v0.1.0 (/mnt/d/MMM/projects/bqy/rust/p2)
    Finished dev [unoptimized + debuginfo] target(s) in 1.13s
     Running `target/debug/p2`
> ls
Cargo.lock  Cargo.toml  src  target
> ls
ls: cannot access 'ls': No such file or directory
> exit
ls: cannot access 'ls': No such file or directory
ls: cannot access 'exit': No such file or directory
> ^C
usn@DESKTOP:~/bqy/rust/p2$ vi src/main.rs

对不良行为的简单解释是未重置命令行。那么,为什么编译器会抱怨?

感谢您的阅读。

没有清除缓冲区的行,它的内容从一个迭代到另一个迭代重复使用。这就是为什么你的程序没有

就不能工作的原因
input = String::from("");

但这会给你一个警告,因为你在声明它时给了 input 一个值:

let mut input = String::new();
//           ^^^^^^^^^^^^^^^^

并且这个值没有被使用,因为input字面上的第一次使用是覆盖它。所以不要给它一个值:

let mut input;

在 Rust 中这是非常安全的,编译器不会让你在初始化之前不小心使用 input


或者,如果您的目标是重用缓冲区以节省内存,您应该使用

input.clear();

因为 input = String::from(""); 使用新缓冲区创建了一个全新的字符串并丢弃了另一个。