我如何调试Rust代码以找出为什么“if”语句不运行?

4

这段代码是我根据《Hands-on Rust》一书中“在数组中搜索”的部分编写的,基本上是从那里复制的。我不知道为什么“if valid”语句没有运行,即使变量应该设置为 true。

use std::io::stdin;
fn main() {
    println!("Please enter the key"); //prints the string
    let mut enter = String::new(); //initiates the changeable variable "enter"
    stdin().read_line(&mut enter).expect(r#"invalid key"#); //allows user input and reads the input to assign into the "enter" variable
    enter.trim().to_lowercase(); //trims the "enter" variable out of non-letter inputs and turns them into lowercase
    let key_list = ["1", "2", "3"]; //the input needed to get the desired output
    let mut valid = false; //initiates the "valid" variable to false
    for key in &key_list { //runs the block of code for each item in the "key_list" array
        if key == &enter { //runs the block of code if the variable "enter" matches the contents of the array "key_list"
            valid = true //turns the "valid" variable into true
        }
    };
    if valid { //it will run the block of code if the variable valid is true
        println!("very nice, {}", enter) //it prints the desired output
    } else { //if the if statement does not fulfill the condition, the else statement's block of code will run
        println!("key is either incorrect or the code for this program sucks, your input is {}", enter) //the failure output
    }
}

如果我的大量注释让你感到不舒服,请见谅。我这样做是为了找出错误所在。


@CodyGray,这与if无关。这只是了解replace如何工作。 - Vega
1
这是一个典型的 XY 问题。 - Vega
2个回答

11

有一个非常棒的宏叫做 dbg! 我喜欢使用它。它就像是充了类固醇的 println!。你可以将其包裹在几乎任何变量、表达式甚至子表达式周围,它会打印其中的代码、值和源位置。

让我们把它加入循环并看看发生了什么:

for key in &key_list {
    if dbg!(key) == dbg!(&enter) {
        valid = true
    }
};

这是我看到的:

Please enter the key
1
[src/main.rs:10] key = "1"
[src/main.rs:10] &enter = "1\n"
[src/main.rs:10] key = "2"
[src/main.rs:10] &enter = "1\n"
[src/main.rs:10] key = "3"
[src/main.rs:10] &enter = "1\n"
啊!enter实际上并没有被修剪。它仍然有尾随的换行符。嗯,为什么呢?我们来看一下trim方法
pub fn trim(&self) -> &str

看起来它返回一个新的&str切片,而不是修改输入字符串。我们知道它不能原地修改它,因为它不使用&mut self

to_lowercase也是一样的:

pub fn to_lowercase(&self) -> String

解决方法:

let enter = enter.trim().to_lowercase();

8
问题在于 stdin().read_line() 会返回带有换行符的输入,但是 str.trim()str.to_lowercase() 并不会改变原始的 str。您需要将其重新赋值给 enter:
enter = enter.trim().to_lowercase();

您可以通过使用Debug格式说明符打印println!("你的输入是:{:?}", enter),或者按照John的建议采用另一种方法来发现它。


我认为Clippy可能会捕捉到OP问题中未使用的结果,但不幸的是它没有标记它。 - BallpointBen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接