25 Minutes of Rust (Episode 5)
In this episode I continue to build a Rust guessing game, using the book "The Rust Programming Language" as a guide.
I'm doing a series of 25 minute sessions where I try to get familiar with the Rust programming language. The blogposts in these series are the notes I took of the lessons learned along the way.
Warning to the reader: As always in this series, these are notes I take as I'm learning. They reflect my current understanding and may be incorrect!
Function Results
In the following lines of code something interesting is happening:
io::stdin().read_line(&mut guess)
.expect("Failed to read line");
The read_line
function doesn't return a number, bit it returns a Result:
io::Result<usize>
The io::Result
is an "Enum". But it seems different from a C# "Enum".
In C# and Enum is more or less a way to give meaning to a numerical value: If a result of "1" indicates success, you can check for Result.Success instead of "1".
The Enum seems more complex in Rust, but the tutorial leaves out quite some details about it at this point.
Most that is said is that the io::Result
enum can have two values:
- Ok
- Err
It also has a function called expect
which you are forced to call, otherwise you get a compiler warning.
When the result is Ok
then expect
will return the usize
result value the read_line
call produced.
If the result us Err
, the expect
function will halt the program and print the given input message to the output.
In the tutorial, at this moment, nothing is done with the resulting usize
value.
Cargo Crates
In Rust, the package manager (like npm or NuGet) is called Cargo. The packages it installs are Crates.
For the guessing tutorial, we install a Crate, rand that can generate random numbers.
I add the crate, via Cargo.toml
and add the following line to my code:
extern crate rand;
The following error appears:
[rustc] use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via
Cargo.toml
instead? (see issue #27812)
This error confused me for some time, it was not clear to me how I could make it use Cargo.toml
instead.
After installing a crate, it turns out, you must reload the project in Visual Studio Code. See Issue #98 of rls-vscode.
Cargo Crate Versioning
According to the book, the crates use semantic versioning (semver). If you add rand = "0.3.14"
, this means to get any version "with an API compatible to version 0.3.14". In practice, this means it'll update to 0.3.15 if it becomes available but not to version 0.4.0, for example.
This struck me as strange, because semver specifies the second version number to be MINOR. Which you increment when you add functionality in a backwards-compatible manner.
One would think it should then be safe to upgrade to 0.4.0 too.
Update June 19th 2018: No less than Rust itself, or at least the twitter account @rustlang, informed me this behaviour is correct:
For versions where the MAJOR version is 0 (0.4.0) the MINOR version behaves like the MAJOR version. According to the semver spec.
If the package version would've been 1.3.0 I would've received 1.4.0 automatically. So Cargo behaves completely as it should!
Anyway, to upgrade, we must run cargo update
.
Conclusion
The concept of Enums in Rust is different from the same concept in C#, from what I can see. I'm looking forward to learning how they are defined.
The VS-Code RLS extension seems to have an issue with new crates, it requires reloading the project. Otherwise it shows a difficult to understand error.
Automatic updating to new versions of crates only goes for PATCH version increments, and only when you explicitly want to. You can do this by running cargo update
.