函数将字符串读取并解析为Rust中的迭代器

函数将字符串读取并解析为Rust中的迭代器,rust,Rust,有没有一种方法可以编写如下所示的函数: fn read\u和iter\u 32\u行迭代器是惰性的。这意味着只要迭代器本身存在,它们所操作的数据就需要存在,但是当函数返回时,buf就不再存在。如果我们保持buf更长时间,它仍然可以工作 编写返回复杂迭代器的函数目前很棘手,但也有可能: use std::io; use std::iter::{Iterator, Map}; use std::str::SplitWhitespace; fn read_and_iter_u32_line(buf:

有没有一种方法可以编写如下所示的函数:


fn read\u和iter\u 32\u行迭代器是惰性的。这意味着只要迭代器本身存在,它们所操作的数据就需要存在,但是当函数返回时,
buf
就不再存在。如果我们保持
buf
更长时间,它仍然可以工作

编写返回复杂迭代器的函数目前很棘手,但也有可能:

use std::io;
use std::iter::{Iterator, Map};
use std::str::SplitWhitespace;

fn read_and_iter_u32_line(buf: &mut String) -> Map<SplitWhitespace, fn(&str) -> u32> {
    buf.truncate(0);
    io::stdin().read_line(buf).unwrap();
    buf.split_whitespace().map(parse)
}

fn parse(s: &str) -> u32 {
    s.parse::<u32>().unwrap()
}
使用std::io;
使用std::iter::{Iterator,Map};
使用std::str::SplitWhitespace;
fn read_和iter_u32_线(buf:&mut字符串)->映射u32>{
buf.截断(0);
io::stdin().读取行(buf).展开();
buf.split_whitespace().map(解析)
}
fn解析(s:&str)->u32{
s、 解析::()。展开()
}

迭代器是惰性的,因此它们必须借用其输入:

  • 这要求他们的输入寿命比他们更长
  • 出于安全原因,这要求在功能边界处公开借用关系
前一点要求将
buf
作为引用而不是值传递

后一点阻止您返回泛型的
迭代器(甚至是装箱的),因为它隐藏了返回的迭代器和传入的缓冲区之间的借用关系。因此,你必须明确:

use std::io;

fn read_and_iter_u32_line<'a>(buf: &'a mut String)
    -> std::iter::Map<std::str::SplitWhitespace<'a>, fn(&'a str) -> u32>
{
    fn convert(s: &str) -> u32 { s.parse().unwrap() }

    buf.truncate(0);
    io::stdin().read_line(buf).unwrap();

    buf.split_whitespace().map(convert)
}

fn main() {
    let mut buf = "".to_string();
    for i in read_and_iter_u32_line(&mut buf) {
        println!("{}", i);
    }
}
使用std::io;
fn read_和_iter_u32_线std::iter::Map u32>
{
fn convert(s:&str)->u32{s.parse().unwrap()}
buf.截断(0);
io::stdin().读取行(buf).展开();
buf.split_whitespace().map(转换)
}
fn main(){
让mut buf=”“.to_string();
对于读取线和输入线中的i(&mut buf){
println!(“{}”,i);
}
}
注意:实际上,生命周期注释可以省略,但我在这里公开它是为了强调为什么通用迭代器不可能