我想编写一个函数 read_vector
,该函数应该从stdin中读取和解析T
类型的项目,然后返回包含这些项目的向量。如果定界符是'n'
,则应分析行,否则所有项目都应在一个分界符分隔的一行中。如果计数不是None
,则表示要读取的项目数。
目标是最大程度地减少代码解复功能并创建一个常规函数,而无需限制类型或其他任何内容。
但是,我遇到了一个我根本无法理解的问题。此代码:
use std::io::{self, BufRead};
fn read_line() -> String {
let mut buf = String::new();
io::stdin()
.read_line(&mut buf)
.expect("failed to read a line");
buf
}
fn parse_iter<'a, Iter, Value>(mut iter: Iter) -> Vec<Value>
where
Iter: std::iter::Iterator<Item = &'a str>,
Value: std::str::FromStr,
<Value as std::str::FromStr>::Err: std::fmt::Debug,
{
iter.map(|x| x.parse().expect("failed to parse")).collect()
}
fn read_vector<T>(count: Option<usize>, delimiter: char) -> Vec<T>
where
T: std::str::FromStr,
<T as std::str::FromStr>::Err: std::fmt::Debug,
{
match count {
None => match delimiter {
'n' => parse_iter(io::stdin().lock().lines().map(|x| x.unwrap())),
_ => parse_iter(read_line().split(delimiter)),
},
_ => match delimiter {
'n' => parse_iter(
io::stdin()
.lock()
.lines()
.map(|x| x.unwrap())
.take(count.unwrap()),
),
_ => parse_iter(read_line().split(delimiter).take(count.unwrap())),
},
}
}
fn main() {
let vector: Vec<u32> = read_vector(None, 'n');
}
导致这些错误:
error[E0271]: type mismatch resolving `<[closure@src/main.rs:27:63: 27:77] as std::ops::FnOnce<(std::result::Result<std::string::String, std::io::Error>,)>>::Output == &str`
--> src/main.rs:27:21
|
27 | 'n' => parse_iter(io::stdin().lock().lines().map(|x| x.unwrap())),
| ^^^^^^^^^^ expected struct `std::string::String`, found &str
|
= note: expected type `std::string::String`
found type `&str`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::io::Lines<std::io::StdinLock<'_>>, [closure@src/main.rs:27:63: 27:77]>`
= note: required by `parse_iter`
error[E0271]: type mismatch resolving `<[closure@src/main.rs:35:26: 35:40] as std::ops::FnOnce<(std::result::Result<std::string::String, std::io::Error>,)>>::Output == &str`
--> src/main.rs:31:21
|
31 | 'n' => parse_iter(
| ^^^^^^^^^^ expected struct `std::string::String`, found &str
|
= note: expected type `std::string::String`
found type `&str`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::io::Lines<std::io::StdinLock<'_>>, [closure@src/main.rs:35:26: 35:40]>`
= note: required by `parse_iter`
我该如何解决问题?
很高兴看到问题的解决方案,而且还建议有关如何改善当前实施的建议,因为它仍然包含许多代码重复,并且仅与stdin一起使用而不是所有可能的流。
<</p>我想出了这个解决方案:
use std::io::{self, BufRead};
fn read_line<T>(mut stream: T) -> String
where
T: BufRead,
{
let mut buf = String::new();
stream.read_line(&mut buf).expect("failed to read a line");
buf
}
fn read_line_from_stdin() -> String {
let stdin = io::stdin();
let stdin = stdin.lock();
read_line(stdin)
}
fn parse_slice_iter<'a, Iter, Value>(iter: Iter) -> Vec<Value>
where
Iter: std::iter::Iterator<Item = &'a str>,
Value: std::str::FromStr,
<Value as std::str::FromStr>::Err: std::fmt::Debug,
{
iter.map(|x| x.trim().parse().expect("failed to parse"))
.collect()
}
fn parse_string_iter<'a, Iter, Value>(iter: Iter) -> Vec<Value>
where
Iter: std::iter::Iterator<Item = String>,
Value: std::str::FromStr,
<Value as std::str::FromStr>::Err: std::fmt::Debug,
{
iter.map(|x| x.parse().expect("failed to parse")).collect()
}
fn read_vector<T, S>(count: Option<usize>, delimiter: char, stream: S) -> Vec<T>
where
T: std::str::FromStr,
<T as std::str::FromStr>::Err: std::fmt::Debug,
S: BufRead,
{
match count {
None => match delimiter {
'n' => parse_string_iter(stream.lines().map(|x| x.unwrap())),
_ => parse_slice_iter(read_line(stream).split(delimiter)),
},
_ => match delimiter {
'n' => parse_string_iter(stream.lines().take(count.unwrap()).map(|x| x.unwrap())),
_ => parse_slice_iter(read_line(stream).split(delimiter).take(count.unwrap())),
},
}
}
fn read_vector_from_stdin<T>(count: Option<usize>, delimiter: char) -> Vec<T>
where
T: std::str::FromStr,
<T as std::str::FromStr>::Err: std::fmt::Debug,
{
let stdin = io::stdin();
let stdin = stdin.lock();
read_vector(count, delimiter, stdin)
}
由于没有模板专业和默认论点等内容,我不得不编写比C 中更多的代码,并发现自己重复了很多东西。我想看看真正的生锈程序员将如何解决问题。