我在Rust中的第一个程序应该以C或F字符的形式从用户那里获取输入:

use std::io;

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

    let mut switch = true;
    while switch {
        println!("source unit? F or C?");
        io::stdin().read_line(&mut srcunit).expect(
            "failed to read src unit",
        );

        if srcunit.trim() == "F" || srcunit.trim() == "C" {
            println!("doing things right with {}", srcunit);
            switch = false;
        } else {
            println!("either F or C, not {}", srcunit);
        }
    }

    println!("you pressed {}", srcunit);
}

当我启动程序并按下F或C时,它工作正常,所以我跳过这里.当我按下另一个角色时,奇怪的部分出现了.我希望我的程序再次请求F或C,直到我按下其中一个字符.当我这样做时,它应该离开while循环,告诉我按下了什么.

source unit? F or C?
G
either F or C, not G //so far so good

source unit? F or C?
F
either F or C, not G //why is F not assigned to the srcunit variable? It's supposed to leave the loop now.
F                    //why does it print this line? I didn't press a key or have a println function/macro that does this

source unit? F or C?
V
either F or C, not G //it's still G, wtf
F                    //again, why are those two lines printed? Where does it store, that I pressed F previously?
V

推荐答案

documentation for read_line人中:

读取所有字节,直到到达一个换行符(0xA字节),然后将它们append个放入提供的缓冲区.

(我的)在读取下一行之前,您需要清除字符串,例如,通过调用字符串上的clear()方法,否则答案将累积在变量中.

或者,您可以在循环中定义变量(但效率稍低,因为这样一来,String将无法为下一个答案重用已分配的存储,它必须重新分配和重新分配).

另见最近被问及的第this question条.看起来这是个常见的trap .

Rust相关问答推荐

将JSON密钥转换为Polars DataFrame

使用Rust s serde_json对混合数据类型进行优化'

borrow 和内部IntoIterator

有没有办法模仿对象安全克隆?

无法理解铁 rust &S错误处理

要求类型参数有特定的大小?

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

为什么这个闭包没有实现Fn?

str 和 String 的 Rust 生命周期

如何从 rust 中的同一父目录导入文件

如何限制通用 const 参数中允许的值?

如何将这些测试放在一个单独的文件中?

`移动||异步移动{...}`,如何知道哪个移动正在移动哪个?

在 Rust 中,将可变引用传递给函数的机制是什么?

为什么 Rust 允许写入不可变的 RwLock?

如何创建递归borrow 其父/创建者的 struct ?

如何在 Rust Polars 中可靠地连接 LazyFrames

字符串切片的向量超出范围但原始字符串仍然存在,为什么判断器说有错误?

如何为枚举中的单个或多个值返回迭代器

基于名称是否存在的条件编译