Please refer to Don Bright’s original rust-lang-cheat-sheet which I based much of this content off, as I worked through the Rust in Motion course by Carol Nichols and Jake Goulding.

Rust in a nutshell

  • Syntax similar to C
  • Ownership of memory enforced at compile time
  • Statically linked
  • Functional-ish, generic-ish, not so objecty
  • Control flow using patterns, match keyword
  • Packages: ‘cargo’ command, https://crates.io
  • Testing: cargo test, #[test]
  • Concurrency: ownership, mutability, channels, mutex, crossbeam + Rayon packages
  • Auto formatter: rustfmt filename.rs
  • Compiler engine: LLVM
  • Raw pointers, low level: unsafe{} keyword

Basics

Documentation

  • rustup doc for offline docs!
  • doc.rust-lang.org standard library, primitive types, standard macros
  • docs.rs for package documentation

Toolchain

$ rustup.sh               # install rust, see rust-lang.org for details
$ cargo new myproj        # start new executable project
$ cargo new --bin myproj  # as above
$ cargo new --lib myproj  # start new library project
$ cd myproj               # cd into the new directory
$ ls -lR                  # list our skeleton of files
src/main.rs               # main.rs, has main() entry point
Cargo.toml                # Cargo.toml defines packaging
$ $EDITOR Cargo.toml      # add dependencies and other details
[package]
name = "helloworld"
version = "0.1.0"
authors = ["Benjamin Simmonds <ben@bencode.net>"]

[dependencies]
serde = "1.0.80"

$ cargo build             # downloads dependencies + builds main.rs
$ cargo build --release   # release build
$ cargo run               # runs program created from main.rs
$ cargo test              # runs tests (in parallel by default)
$ cargo test -- --test-threads=1  # run tests one at a time
$ cargo test -- --nocapture       # run tests, show output
$ cargo run --example fundemo -- --argtodemo # run example with argument

Mutability

let x = false;           // all variable bindings are immutable by default
x = true;                // compile error: can't change an immutable binding
let mut p = false;       // "mut" designates a binding as mutable
p = true;                // ok, mutable binding can change;

Types and variables

let x: bool = false; // let keyword
let k = false;       // rustc can determine some types, this is idiomatic rust
let y: char = '上';  // all chars are 4 bytes
let  = 5;          // error. identifiers must be ASCII characters
let a: i8 = -2;      // 8 bit signed integers, also i16, i32, i64
let b: u8 = 200;     // 8 bit unsigned integers, also u16, u32, u64
let n: f32 = 0.45;   // 32 bit float (automatcally converted+rounded from decimal to binary)
let n = 42.01f64;  c // 64 bit float literal of the number 42.01 (approximately)
let r: [u8;3] = [3,4,5];          // array of 3 int, cannot grow
let s = [0;500];                  // array of 500 integers, each initialized to 0
let s = &r[0..2];                 // slice of array, s==&[3,4]
let s = &r[0..2][0];              // index into slice, s==3
let mut u:Vec<u8> = Vec::new();   // create empty vector of unsigned 8 bit int, can grow
let mut v = vec![3,4,5];          // initialize mutable vector using vec! macro
let w = vec![1,12,13];            // vectors can be immutable too
u.push( 2 );                      // append item to vector
u.pop();                      // vectors can return+remove last input (like a stack)
v.contains(&3);               // true if vector contains value
v.remove(1);                  // remove the nth item from a vector...
v.append(u);                  // append v with u (u becomes empty ([]), both mutable)
v.extend(w);                  // extend v with w (v owns w, w can be immutable)
v.resize(200,0);              // make vector have 200 elements, set them to 0
let x = &w[1..];              // get a slice of a vector (a view into it's elements)
print("{:?}",x);              // [12,13];
let vs = v.len();             // length of vector
let (p,d,q) = (4,5,6);        // tuple() can assign multiple variables at once
print("{}",p);                // you can use them alone after tuple assignment
let m = (4,5,"a");            // tuples can have multiple different types as elements
let (a,b) = m.0, m.2;         // tuple indexing with .0, .1, .2, etc
let (a,b) = m.p, m.q;         // error, cannot index into a tuple using a variable
let (x, y, z) = m;            // tuple destructuring into individual variables

let s = String::from("上善若水");  // String
let s2 = "水善利萬物而不爭";       // string literal, type is &str
let s3 = format!("{}{}",s2,s3);    // concatenate strings
for i in "말 한마디에 천냥 빚을 갚는다".split(" ") {print!("{}",i);} // split string
let s4 = s.get(0..2);              // Substring using indexes
let i4 = s.find('水').unwrap_or(-1); // find index of character (not a byte offset)
let hellomsg = r###"               // Multi-line with embedded quotes
 "Hello" in Chinese is 你好 ('Ni Hao')
 "Hello" in Hindi is नमस्ते ('Namaste')
"###;

usize, isize              // this is the pointer size. used in loops, vector length, etc

const BILBOG: i32 = 10;         // constant
static ORGOG: &str = "zormpf";  // static, global-ish variable
static FOOBY: i32 = 5;          // unsafely mutable
static Z_ERRMSG : [&str;2] = ["need input","need more input"]; // static strings

type Valid = bool;        // typedef ( make your own type names )

let mut v = vec![1u8,2u8,3u8];  // determine the type of expression expr by looking at rustc error
println!("{}",v.iter_mut());    // for example, if we want to know the type of v, build an error
12 |     println!("{}",v.iter_mut());   // type of v.iter_mut() is std::slice::IterMut<'_, u8>`
   |                   ^^^^^^^^^^^^ `std::slice::IterMut<'_, u8>` <- error line tells you the type