Я работаю над курсом, который использует автоматизированные тесты. Ввод предоставляется в виде стандартного ввода, а затем вы печатаете ответы на стандартный вывод.
Поскольку ввод обычно принимает форму набора значений одного типа, разделенных пробелами, и я не хочу снова и снова писать один и тот же код, я пытаюсь написать функцию для анализа ввода в вектор заданного тип. Однако моя проблема заключается в том, что я хочу использовать универсальный, чтобы указать, какой тип функция будет пытаться анализировать данные. Я не знаю, как это сделать. Мой текущий код:
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
, как вы делаете сейчас).