gpt4 book ai didi

rust - 创建拥有一些中间数据并指向它的迭代器的惯用方式是什么?

转载 作者:行者123 更新时间:2023-12-03 11:31:36 26 4
gpt4 key购买 nike

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

我想用输入的当前行保留一个String,并使用其当前 token 保留一个SplitAsciiWhitespace迭代器。当我到达迭代器的末尾时,我想换一行。

我不担心错误检查,也不对任何包装箱感兴趣。这不是用于生产代码,而只是用于练习。我想避免使用unsafe来练习正确的心态。

我的想法是可以按以下方式使用它:

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()
}
}

This question解释了为什么不能通过这种方式但没有提供替代解决方案的原因。 “如何修复它”部分只是说“不要将这两件事放在同一个结构中”,但是我想不出一种单独的方法来保持与用户相似的界面。

最佳答案

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

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

不知道这是否算作“惯用的” Rust。

struct Reader {
line: String,
offset: usize,
}

impl Reader {
fn new() -> Self {
Reader { line: String::new(), offset: 0 }
}
fn next<T: std::str::FromStr + std::default::Default> (&mut self) -> T {
loop {
let rem = &self.line[self.offset..];
let token = rem.split_whitespace().next();
if let Some(token) = token {
self.offset = token.as_ptr() as usize - self.line.as_ptr() as usize + token.len();
return token.parse::<T>().unwrap_or_default();
}
self.line.clear();
std::io::stdin().read_line(&mut self.line).unwrap();
self.offset = 0;
}
}
}

关于rust - 创建拥有一些中间数据并指向它的迭代器的惯用方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61308010/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com