Skip to main content

Rust

Geoffrey Hunter
mbedded.ninja Author

Overview

Rust is relatively new, statically typed, non garbage collected "systems" programming language. The most unique aspect about Rust compared to similar languages (such as C, C++) is Rusts ownership model (more on this below), which aims to completely eliminate specific memory bugs and race conditions that are common in similar languages.

The logo of the Rust programming language. Image from http://www.rust-lang.org/.

Getting Started

Install Rustup

The easiest way to get started with Rust is to install Rustup, a Rust installer and version management tool.

On a Linux, macOS or other UNIX-like OS:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

This will typically provide you with a prompt with options --- accept the defaults to install.

On Windows:

Download rustup-init.exe from the Rust website and run the installer.

If you are using the Windows Subsystem For Linux (WSL), you can use the instructions above for UNIX-like OS's.

Create A New Project With cargo

cargo new hello-world

cargo should setup a basic project for you. You can now run the template by doing the following:

cd hello-world
cargo run
Compiling AdventOfCode2019 v0.1.0 (/Users/ghunter/code/AdventOfCode2019)
warning: crate `AdventOfCode2019` should have a snake case name
|
= note: `#[warn(non_snake_case)]` on by default
= help: convert the identifier to snake case: `advent_of_code2019`

Finished dev [unoptimized + debuginfo] target(s) in 4.55s
Running `target/debug/AdventOfCode2019`
Hello, world!

Ownership

The most unique aspect of the Rust language is it's ownership model. This ownership system combines ownership, borrowing and copying concepts and relies heavily on zero-cost (no run-time influence) compiler checks to implement it. The system is designed to prevent common software issues relating to concurrency and data races.

fn main() {

}

Lifetimes Of References

Every reference in Rust comes with a lifetime, although in many cases Rust will let you omit the lifetime syntax and the references lifetime will be implied by the context. Lifetimes are specified by '<identifier>, e.g. 'a would read the "lifetime of a", and 'xyz the "lifetime of xyz".

fn my_fn(my_object: MyObject&) { // Implied lifetime (length of function)
...
}

struct MyStruct<'a> {
my_object: MyObject& 'a // Explicit lifetime
}

You can read more about the ownership system in the official Rust book.

Casting

Basic type casting is done is Rust with the as operator:

let x: u32 = 22;
let y: i32 = x as i32;

Printing To stdout

Rust provides you with the println!() macro to perform basic printing to stdout. It supports a C-like variable length argument syntax with the string as the first parameter, and then successive parameters being the replacement variables. While C uses %s,%u, e.t.c to denote locations for replacement, Rust uses {}:

println!("My variable = {}", my_var);

You do not have to import any module to call println!().

Source Code

The source code for Rust is maintained on GitHub at https://github.com/rust-lang/rust.

Online Editor

You can write and run Rust test code online at the Rust playpen.

Embedded Platforms

Rust is beginning to be used on embedded platforms (however, it is still in a mostly experimental manner). There is discussion of the suitability of rust for an embedded platform at Atomic Object.

zinc.rs is an attempt to write an ARM stack (similar to CMSIS or mbed in functionality, which are both written in C) using the rust programming language.

IDE Support

The Rust (rls) extension for Visual Studio Code adds Rust code completion, jump to definition, peek definition, find all references, symbol search, documentation on hover, code formatting, refactoring, error squiggles, snippets, build tasks and more.

Containers

HashMap

Known in other languages as a map, dictionary (Python).

To add a value use the insert() method. The following example adds the value 2 to the key "mykey".

my_hashmap.insert("mykey", 2);

To retrieve a value at a certain key, use the get() method:`

let value = my_hashmap.get("mykey");
if let Some(v) = value {
println!("Got value of {}", value);
}

Dealing With Unrecoverable Errors

You can cause the current thread to panic with the panic!() macro. This will cause the current thread to terminate. If you happen to be on the main application thread, this will cause the application to exit:

panic!("Something really bad happened!");

which will produce output similar to:

thread 'main' panicked at 'Something really bad happened!', src/main.rs:2:5