6
votes

I want the user to pass in command-line arguments to a simple function I've written in Rust. I know that I can use int::from_str(args[1]) to convert, but this returns an Option<int>, which means in order to pass it into a function that takes an int, like the one below, I have to use a match statement. But with n arguments, there are 2^n possibilities. Writing a series of nested match statements with something would be terrible. It would be ideal if there were a way to do something like:

// will return either Some(int) or None
let start = int::from_str(args[1]), end = int::from_str(args[2]);
if typeof(start) == Some && typeof(end) == Some { 
    println(fmt!("You entered: %d, %d", start, end); 
} else { 
    println("Error with arguments."); 
}

Is there any such method? That lets me test which member of an enum something is besides match?

1

1 Answers

7
votes

The variants of an enum are all the same type (in this case, both None and Some(foo) are Option<int>), so what you actually want to do is check which variant start and end are. Fortunately Rust provides several options.

A direct translation of your code would be to use start.is_some() && end.is_some(). However this requires modifying the format string to be fmt!("You entered: %d, %d", start.get(), end.get()), because start and end are not integers, but still wrapped in the Some(...) variant. (This variant-test is something that has to be written on a per-enum basis, there's no build-in functions that allow you to perform the test for any enum.)

The more idiomatic way would be something like this:

// will return either Some(int) or None
let start_opt = int::from_str(args[1]), end_opt = int::from_str(args[2]);
match (start_opt, end_opt) { 
    // only matches if both are Some
    (Some(start), Some(end)) => println(fmt!("You entered: %d, %d", start, end),

    // will match when either (or both) are None
    _                        => println("Error with arguments.");
}