Smith
Smith

Reputation: 1448

How to implement a python-like input function in Rust using generic types?

I made a python-like input function to get stdin and return a String. It was working fine, I got the result and it was parsing into whatever numeric type needed. But, I decided to move parsing to the function and use a generic type on it, then I got an error.

Here's the code:

fn input<T>(text: &str) -> T {
    let mut input = String::new();

    println!("{}", text);
    std::io::stdin()
        .read_line(&mut input)
        .expect("Erro ao ler valor");

    let input = input.trim().parse::<T>().expect("Erro ao ler valor");

    return input;
}

The error in compilation:

let input = input.trim().parse::<T>().expect("Erro ao ler valor");
                         ^^^^^ the trait `FromStr` is not implemented for `T`

Also, in VSCode, this message is shown:

main.rs(9, 11): consider restricting type parameter `T`: `: std::str::FromStr`

I think I could use enumeration to fix this, but it would be hard to write down every possible type accepted by println, and use conditional statement seems to be even worse. I've been studying Rust for three days so far and I don't really know the right approach.

Upvotes: 0

Views: 236

Answers (1)

cdhowie
cdhowie

Reputation: 169281

The compiler tells you what to do:

use std::str::FromStr;

fn input<T: FromStr>(text: &str) -> T {
//        ^^^^^^^^^

This bounds the generic type T and says that it must implement the FromStr trait, which is required for .parse::<T>() to work (the parse function bounds on T: FromStr as well).

Further reading:

Upvotes: 1

Related Questions