Generic return without generic argument

Advertisements

I am working on a course which uses automated tests. The input is given in the form of standard input and you then print the answers to standard output.

As the input usually takes the form of a bunch of values of the same type separated by spaces and I don’t want to write the same code again and again I am trying to write a function to parse the input to a vector of a given type. However, my problem is that I want to a use a generic to specify what type the function will attempt to parse the data as. I don’t know how to do that. My current code is:

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

How can I make this work?

>Solution :

You are almost there. Just make your function generic over T:

fn std_in_to_vec<T>(split_on: &str) -> std::io::Result<Vec<T>> {
    // ...
}

You specify which version of this function you want at the call site. You can either make compiler infer what T is:

let input: Vec<i32> = std_in_to_vec()?;

Or specify it using turbofish syntax:

let input = std_in_to_vec::<i32>()?;

Also note that you are returning io::Result, but you are calling expect on read_line. That doesn’t make a lot of sense. Either propagate the error (using for example ? operator), or keep panicking on it (and in that case remove io::Result from returned type).

And my final comment is that stdin is one word.

Leave a Reply Cancel reply