Я работаю над курсом, который использует автоматизированные тесты. Ввод предоставляется в виде стандартного ввода, а затем вы печатаете ответы на стандартный вывод.
Поскольку ввод обычно принимает форму набора значений одного типа, разделенных пробелами, и я не хочу снова и снова писать один и тот же код, я пытаюсь написать функцию для анализа ввода в вектор заданного тип. Однако моя проблема заключается в том, что я хочу использовать универсальный, чтобы указать, какой тип функция будет пытаться анализировать данные. Я не знаю, как это сделать. Мой текущий код:
fn std_in_to_vec(split_on: &str) -> std::io::Result<Vec<T>> {
// read in stdin line
let mut stdin_buffer = String::new();
std::io::stdin().read_line(&mut stdin_buffer).expect("could not read stdin");
// split and read to vec
let input: Vec<&str> = stdin_buffer.trim().split(" ").collect();
// attempt to parse as type
let mut parsed: Vec<T> = Vec::with_capacity(input.len());
for val in input {
parsed.push(val.parse::<T>().expect("could not parse as type"));
}
Ok(parsed)
}
Как я могу заставить это работать?
Вы почти там. Просто сделайте свою функцию универсальной поверх T:
fn std_in_to_vec<T>(split_on: &str) -> std::io::Result<Vec<T>> {
// ...
}
Вы указываете, какую версию этой функции вы хотите на месте вызова. Вы можете заставить компилятор сделать вывод, что такое T:
let input: Vec<i32> = std_in_to_vec()?;
Или укажите его, используя синтаксис turbofish:
let input = std_in_to_vec::<i32>()?;
Также обратите внимание, что вы возвращаетесь io::Result, но звоните expect на read_line. Это не имеет особого смысла. Либо распространите ошибку (используя, например, оператор ?), либо продолжайте паниковать (и в этом случае удалите io::Result из возвращаемого типа).
И мой последний комментарий: stdin — это одно слово.
Примечание: вы не должны collect получить результат split, который вызывает ненужное выделение памяти. Вместо этого итерируйте непосредственно split: for val in stdin_buffer.trim().split(" ") (и да, это означает, что вы больше не можете заранее выделять емкость для parsed, но это не хуже, чем не выделять предварительно емкость для input, как вы делаете сейчас).