Rust 什么';创建拥有一些中间数据并指向它的迭代器的惯用方法是什么?

Rust 什么';创建拥有一些中间数据并指向它的迭代器的惯用方法是什么?,rust,Rust,我正在尝试创建一个围绕stdinstd的结构,以提供类似于C++的std::cin 我想用输入的当前行保留一个字符串,并将SplitAsciiWhitespace迭代器保留到其当前标记。当我到达迭代器的末尾时,我想得到一个新行 我不担心错误检查,我对任何板条箱都不感兴趣。这不是为了生产代码,只是为了练习。我想避免使用不安全的,作为练习正确心态的一种方式 我的想法是,我可以如下使用它: let mut reader = Reader::new(); let x: i32 = reader.read

我正在尝试创建一个围绕stdin
std
的结构,以提供类似于C++的
std::cin

我想用输入的当前行保留一个
字符串
,并将
SplitAsciiWhitespace
迭代器保留到其当前标记。当我到达迭代器的末尾时,我想得到一个新行

我不担心错误检查,我对任何板条箱都不感兴趣。这不是为了生产代码,只是为了练习。我想避免使用不安全的,作为练习正确心态的一种方式

我的想法是,我可以如下使用它:

let mut reader = Reader::new();
let x: i32 = reader.read();
let s: f32 = reader.read();
我当前的尝试如下,但它无法编译。有人能给我一个正确的方法吗

struct Reader<'a> {
    line: String,
    token: std::str::SplitAsciiWhitespace<'a>,
}

impl<'a> Reader<'a> {
    fn new() -> Self {
        let line = String::new();
        let token = line.split_ascii_whitespace();
        Reader { line, token }
    }

    fn read<T: std::str::FromStr + std::default::Default>(&'a mut self) -> T {
        let token = loop {
            if let Some(token) = self.token.next() {
                break token;
            }
            let stdin = io::stdin();
            stdin.read_line(&mut self.line).unwrap();
            self.token = self.line.split_ascii_whitespace();
        };
        token.parse().unwrap_or_default()
    }
}
struct读取器,
}
恳求{
fn new()->Self{
让line=String::new();
让token=line.split_ascii_whitespace();
读卡器{line,token}
}
fn读取(&'a mut self)->T{
让令牌=循环{
如果让Some(token)=self.token.next(){
中断令牌;
}
设stdin=io::stdin();
标准读取行(&mut self.line).unwrap();
self.token=self.line.split_ascii_whitespace();
};
token.parse()
}
}

解释了为什么不能这样做,但没有提供替代解决方案。“如何修复它”一节简单地说“不要将这两件事放在同一个结构中”,但我想不出一种方法来分别处理,同时为用户保留一个类似的界面。

找到了一个解决方案:使用一个简单的索引来跟踪到目前为止我们读取了多少字符串

它确实需要一些指针算法,但似乎工作得很好

不确定这是否算作“惯用”生锈,tho

结构读取器{ 行:字符串, 抵销:usize, } impl阅读器{ fn new()->Self{ 读取器{line:String::new(),偏移量:0} } fn下一步(&mut self)->T{ 环路{ 设rem=&self.line[self.offset..]; 让token=rem.split_whitespace().next(); 如果让一些(令牌)=令牌{ self.offset=token.as_ptr()as usize-self.line.as_ptr()as usize+token.len(); return token.parse::().unwrap_或_default(); } self.line.clear(); std::io::stdin().read_行(&mut self.line).unwrap(); self.offset=0; } } }
链接问题的主要答案确实有一个“如何修复它?”部分。这个问题应该解释为什么这一部分不适用于这里。你可能会做些什么来解决这个问题:链接的问题在其建议的解决方案中有点过于笼统。“我只是在想它在我的案例中是如何应用的,或者是否有更好的方法来解决这个问题。”彼得哈尔,我最终找到了一个类似的解决方案。我只是想知道是否有一种方法可以不使用
不安全的
。我将把这一点补充到问题中。