Общий возврат без общего аргумента

Я работаю над курсом, который использует автоматизированные тесты. Ввод предоставляется в виде стандартного ввода, а затем вы печатаете ответы на стандартный вывод.

Поскольку ввод обычно принимает форму набора значений одного типа, разделенных пробелами, и я не хочу снова и снова писать один и тот же код, я пытаюсь написать функцию для анализа ввода в вектор заданного тип. Однако моя проблема заключается в том, что я хочу использовать универсальный, чтобы указать, какой тип функция будет пытаться анализировать данные. Я не знаю, как это сделать. Мой текущий код:

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

Как я могу заставить это работать?

Примечание: вы не должны collect получить результат split, который вызывает ненужное выделение памяти. Вместо этого итерируйте непосредственно split: for val in stdin_buffer.trim().split(" ") (и да, это означает, что вы больше не можете заранее выделять емкость для parsed, но это не хуже, чем не выделять предварительно емкость для input, как вы делаете сейчас).

Jmb 17.02.2023 09:22
Как создавать пользовательские общие типы в Python (50/100 дней Python)
Как создавать пользовательские общие типы в Python (50/100 дней Python)
Помимо встроенных типов, модуль типизации в Python предоставляет возможность определения общих типов, что позволяет вам определять типы, которые могут...
4
1
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы почти там. Просто сделайте свою функцию универсальной поверх 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 — это одно слово.

Другие вопросы по теме