Correct use of enums in a match

Just got started with Rust last week, so a beginner here!

Need help to understand the correct use of enums for doing stdin with a fixed set of alternatives.

In the match statement, I get an error that says "Expected function, got enum variant".

How do I resolve this? Also, how does one craft an output method for enums - is that recommended? I would also like to understand how to handle any non-standard input - is there a way to catch exceptions on the fly when doing the stdin operation?

use std::io::Read;

use std::io;

fn main() {

    enum fruitKind {

        Apple,

        Orange,

    }

    println!("Enter your favourite fruit: ");

    let mut fruit = String::new();

    io::stdin().read_line(&mut fruit);

    let favFruit = match fruit {

        Apple => fruitKind::Apple,

        Orange => fruitKind::Orange,

    };

    println!("Your favourite fruit is: {}", favFruit);

}

When you do match fruit, since fruit is a String (i.e., a heap-allocated growable string), so you'd need to match against String literals or String constants.

But there is no such thing as String literals, and the only String constant you can currently make is the empty String (since it is the only one that does not need to heap-allocate).

What you are looking for, is rather to match on a view over the string itself (the sequence of chars, of sorts), a &str. You can obtain by calling .as_str() on your String.

At that point, you need now need to match against &str literals or constants, which is great, since "literals like this one" are precisely of type &str:

match fruit.as_str() {
    "Apple" => { ... },
    "Orange" => { ... },
    // Otherwise / catch-all pattern
    _ => { ... }

which gives:

use ::std::{
    io::{self,
        // Read,
    },
};

fn main ()
{
    #[derive(Debug)] // allows using {:?} formatting
    enum FruitKind {
        Apple,
        Orange,
    }

    println!("Enter your favourite fruit: ");

    let mut fruit = String::new();

    io::stdin().read_line(&mut fruit).unwrap();

    let fav_fruit = match fruit.as_str() {
        "Apple" => FruitKind::Apple,
        "Orange" => FruitKind::Orange,
        // Otherwise
        _ => {
            println!("Error, that fruit is not recognized");
            return;
        },
    };

    println!("Your favourite fruit is: {:?}", fav_fruit);
}

Regarding

I guess you mean / want to display / print the enum variant. This is done by using

  • either the Display formatting ({}), which corresponds to the nice human-looking machinery, and which needs to be manually implemented and is thus a bit cumbersome to do in Rust,

  • or the Debug formatting ({:?}, if you come from Python, this would be closer to the __repr__ and its {!r} formatting), which will remain quite close to the source code representation of your type, since using it is rather intended to be done for debugging purposes, hence its name. Given the loose constraints on the specifics of the output to display, Rust will happily do it for you, provided you add a #[derive(Debug)] on the type definition (taking Python as an example again, imagine that being a decorator that auto-generates a nice __repr__ implementation).

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.