繁体   English   中英

为什么 rust 的 read_line 函数使用可变引用而不是返回值?

[英]Why does rust's read_line function use a mutable reference instead of a return value?

考虑这段代码来读取 rust 中的用户输入

use std::io;
fn main() {
    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .expect("error: unable to read user input");
    println!("{}", input);
}

为什么没有办法这样做?

use std::io;
fn main() {
    let mut input = io::stdin()
        .read_line()
        .expect("error: unable to read user input");
    println!("{}", input);
}

其他语言会更方便

原因是read_line没有针对小型交互程序进行优化; 更好的方法来实现这些。

read_line方法来自通用的io::BufRead trait,它的主要用途是读取可能大量的输入。 这样做时,尽量减少执行的分配次数是有利的,这就是read_line旨在重用现有字符串的原因。 一个典型的模式是:

let mut line = String::new();
while input.read_line(&mut line)? != 0 {
    // do something with line
    ...
    line.clear();
}

这确保(重新)分配的数量保持最少,因为line只会根据需要增长以适应输入线。 一旦达到典型大小,分配将变得非常罕见,一旦读取到最大行,它们将完全消失。 如果read_line()支持“convenient”接口,那么上面的循环确实会更好看——例如:

while let Some(line) = read_new_line(some_input)? {
    // process the line
    ...
}

...但需要对每一行进行新的分配和解除分配。 BufRead或学习程序中,这完全没问题,但BufRead旨在作为高效IO 的构建块,因此其read_line方法有利于性能而不是方便。 虽然在BufRead::read_line方面实现更方便的行读取方法是微不足道的, BufRead::read_line是不可能的。

例如,这是一个分配read_line变体的实现,它允许使用如上所示( 游乐场):

use std::io::{self, BufRead};

fn read_new_line(mut input: impl BufRead) -> io::Result<Option<String>> {
    let mut line = String::new();
    if input.read_line(&mut line)? == 0 {
        return Ok(None);
    }
    Ok(Some(line))
}

请注意,为了在while循环中使用,类似read_new_line东西已经以BufRead::lines()的形式存在,它在新分配的行上返回一个迭代器。 尽管如此,此迭代器仍被设计为与迭代一起使用,因此在问题中显示的代码中并不方便。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM