0:00
/
0:00
Transcript

More Rust Iterators

A program using iterators to process command-line args.

GitHub source code: https://github.com/caveofprogramming/rust/

In this video I’ve put together a program that parses command-line args (a string and an integer) using iterators, rather than collecting them in a vector.

You can see the full program via the GitHub link above, or in the video.

I’ve used the following techniques in the program.

Retrieving Arguments

You can specify program arguments when you run via cargo like this:

cargo run — hello to you

hello, to and you become arguments to the program being run.

To retrieve these arguments in the program we can use:

args gets set to an object which implements the Iterator trait.

Passing Arguments to a Function

To pass this variable to a function, we can specify that the argument implements the Iterator trait, and specifically, an Iterator over strings.

next() actually returns an Option<T>, so we have to unwrap it to get at the actual string argument.

Since the first argument is always the name of the program, and my program is called “iterator”, this prints

When I run it with cargo.

Unwrapping with Match and Returning a Result

Here I’ve written some code that retrieves the first user-supplied argument and returns it from a function, in the Ok value of the Result enum.

If there’s no such argument, the function returns Err.

The Ok value wraps a String, because it’s supplied by the user via the command line.

The Err value returns a &str, because it’s hardcoded into the program. It has a lifetime of ‘static, for the same reason.

Retrieving a Numerical Argument

The following function does the same thing, except it expect the argument (now an age) to be an unsigned integer.

As before, next() gets us the next argument from the args iterator. This returns a Option<T>, having the values either Some or None.

ok_or() then translates the Option<T> into a Result<T>. If the Option was set to Some, it gets the value from Some and wraps it with Ok. Otherwise it wraps the supplied message with Err.

The question mark after ok_or() then returns from the get_age_arg() function with the Err if no argument could be retrieved, otherwise it unwraps the value contained in Ok.

parse::<u32>() then tries to parse the string argument into an unsigned 32-bit integer. This returns a Result: Ok wraps the value if the parse was successful, otherwise Err wraps an error value.

However, the error value isn’t just a &str, so we can’t add a question mark to just return from the function in case of error.

Instead, we use map_err() with a closure to translate the Err into an Err containing a string.

That’s now compatible with the return type of get_age_args(), so we can use a question mark to return from the function in case of an error.

Discussion about this video