Я пытаюсь создать структуру, которая охватывает stdin
, чтобы обеспечить что-то вроде std::cin
.
в C ++. Я хочу сохранить String
с текущей строкой ввода и 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()
}
}
Этот вопрос объясняет , почему это не может быть сделано таким образом, но не предоставить альтернативное решение. В разделе «Как это исправить» просто говорится «не помещайте эти две вещи в одну и ту же структуру», но я не могу придумать, как сделать это отдельно, сохранив интерфейс, подобный пользователю.