Rust has been on my radar for some time and I aspire to become proficient with the Rust Programming Language in 2019. Initially, my interest in Rust was sparked by the memory ownership model. With WASM support going mainstream I thought I’d give Rust a deeper look and have enjoyed my experience so far.
This post is a living post that will continue to be revised and appended as I learn more about Rust.
I hope you find this post helpful.
- Established January 21, 2019
- Added “Exploring Structs, Methods, and Associated Functions” on January 21, 2019
- Added “Working with Enums” on January 21, 2019
- Added “Ownership” on January 21, 2019
First Steps with Rust Programming
Your first step with Rust are made easy thanks to Rust Playground. You can play with Rust online without having to install any software on your local machine.
Installing Rust on a MacBook Pro
$ curl https://sh.rustup.rs -sSf | sh
Once the installation program was downloaded and executed I needed to make one
modification to my environment. The Rust installation program tried to update
my environment automatically to add
~/.cargo/bin to my
$PATH; however, I’ve
established my own (crude) dotfiles which modify my exports in a non-standard way.
So, I edited my .exports directly.
To confirm Rust was installed I ran the following command and verified Rust version
1.24.1 was installed.
$ rustc --version
To confirm my
$PATH was properly configured I closed and reopened my terminal and typed the following command and verified my cargo bin was included within the path
$ print $PATH /Users/aarongreenlee/.cargo/bin:/usr/local/bin: ... and a bunch of other paths
Stub an Application with Cargo
With the environment configured the next step was to use Rust’s package manager and build tool called Cargo to create a new application.
Run the following command in any directory you like to store code in which will create a new directory called
$ cargo new --bin hello-world
Cargo establishes the following:
├── Cargo.toml // Program Manifest └── src └── main.rs // Program Entry-point
Running Rust Code
From within the root directory of your application, run:
$ cargo run
The following snippet explores some basic data types and introduces a concept I rather like: data mutability. By default, variables are not mutable in Rust. You need to declare that a variable is mutable (e.g., it can be changed) by adding the
Running the above program prints the following to stdout (e.g., your terminal):
immutable_int is 5 mutable_int is 6 immutable_int != mutable_int the first letter in Aaron's name is 'a' values 1 true and z last item in the array is 0.2
Exploring Structs, Methods, and Associated Functions
Running the above code outputs the following:
Working with Enums
The programmer example above can be improved by adding support for Enums. The materially different code is commented:
The programmer program has now been refactored to use enums to identify programming languages. The output is unchanged:
Ownership is Rust’s strategy for managing data in memory and avoiding memory management problems common to other languages. Every chunk of data has a single variable which is the owner, and there can only be one owner. The owner is responsible for cleaning up data from memory when no longer needed. Clean-up automatically occurs when the variable is no longer in scope (similar to garbage collection but without magic).
Ownership is different from manually managing memory (e.g., C). Ownership avoids memory management problems such as the corruption which will occur when two parts of code try to free the same memory, or when a program attempts to access memory after another part of the program has released that memory.
In memory, a string variable looks like this:
When the variable
a goes out of scope, the above data in memory needs to be released.
Ownership is movable (transferable). Consider the situation
let b = a;. Such an assignment transfers the ownership of
b. Rust moves ownership by default for non-primitive data types.
Moving Ownership: Example 1
Moving Ownership: Example 2
Cloning to maintain ownership when sharing
The following example results in an error. Once ownership transferred to the
say() function we no longer allowed to work with that memory in the
To continue working with
a in the above example we need to allocation more memory. This trade off may result in more memory being used but ensures common mistakes
will not occur. The following example showcases how we can
clone the variable
a and transfer ownership of the clone to
say. Ownership of
a is retained by
a variable and the
s argument establishes ownership of