我想将此 Python 代码转换为 Rust:
for line in sys.stdin:
do something to the whole line including \n
Run Code Online (Sandbox Code Playgroud)
但我只能找到读取单个整行(包括\n)的示例或不读取\n.
看起来这应该是世界上最简单的,但我一直找不到它。
Python和Rust都提供了方便的 API 来迭代文件中的行,它们只是选择了便利性与完整性之间的不同权衡。Rust 选择了额外的便利并去除了换行符,但代价是无法区分最后一行是否以终止符结尾。Python 选择了相反的方法,代价是所有行解析器都必须考虑到final \n,并且还考虑到它是可选的。
但这BufRead::lines()只是一种方便的方法;如果它不能满足您的需求,您可以read_line()直接使用:
let mut line = String::new();
while input.read_line(&mut line)? != 0 {
let line = std::mem::take(&mut line);
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果您在多个地方使用此类代码,或者只是想要循环的便利for,您可以将其抽象为返回迭代器的实用函数,例如:
fn full_lines(mut input: impl BufRead) -> impl Iterator<Item = io::Result<String>> {
std::iter::from_fn(move || {
let mut vec = String::new();
match input.read_line(&mut vec) {
Ok(0) => None,
Ok(_) => Some(Ok(vec)),
Err(e) => Some(Err(e)),
}
})
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用for类似于 Python 中的循环:
for line in full_lines(io::stdin().lock()) {
let line = line?;
// ...
}
Run Code Online (Sandbox Code Playgroud)
通过额外的努力,甚至可以对full_lines任何实现的方法创建一个方法BufRead:
trait FullLines: BufRead + Sized {
fn full_lines<'a>(self) -> Box<dyn Iterator<Item = io::Result<String>> + 'a>
where
Self: 'a,
{
Box::new(full_lines(self))
}
}
// Provide a blanket implementation of FullLines for any T
// that implements BufRead
impl<T: BufRead> FullLines for T {}
// Usage:
use FullLines;
for line in io::stdin().lock().full_lines() {
let line = line?;
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3100 次 |
| 最近记录: |