在Rust中比较字符串

15

我想将来自stdin的字符串输入与一个静态字符串进行比较,但没有成功。

这是我迄今为止尝试过的:

fn main() -> () {
    let mut line = "".to_string();
    let exit = "exit".to_string(); 

    while line.as_slice() != exit.as_slice() {
        let input = std::io::stdin().read_line().ok();

        line.push_str( input.unwrap().to_string().as_slice() );

        assert_eq!(line, exit);
    }   
}

然而在断言期间出现了失败。在Rust中,我应该如何比较一个字符串输入和一个静态字符串?

非常感谢您的帮助。

1个回答

24

首先,该行包含行终止符。你可能希望使用trim(或其变体之一)来忽略它。

其次,您执行了许多不必要的转换和分配操作。尽量避免这些操作。

第三,to_string(或者至少是我最后检查时的情况)由于过度分配而效率低下。您需要使用into_string

第四,从String&str的最快方式是"交叉借用";给定一个String s&*s将重新借用它作为&str。这是因为String实现了Deref<&str>;换句话说,String的行为有点像指向借用字符串的智能指针,使其可以退化成更简单的形式。

第五,除非您正在做一些不寻常的事情,否则可以使用lines迭代器方法将其重写为for循环。

第六,请注意,stdin()每次调用都会分配一个新的缓冲读取器。不仅如此,而且读入缓冲区的字符在创建新缓冲区时不会被推回到标准输入流中;这些数据只是丢失了。因此,您真的不应该在循环中调用它。如果需要,请调用一次并将结果保存在变量中。

因此,最终代码如下:

fn main() {
    for line in std::io::stdin().lines() {
        // Extract the line, or handle the error.
        let line = match line {
            Ok(line) => line,
            Err(err) => panic!("failed to read line: {}", err)
        };

        assert_eq!(line.trim(), "exit");
    }
}

1
谢谢。我没有意识到从STDIN输入的字符串包含换行符。 - Joshua Partogi

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