RUST 101

OUTLINE

  • WHY RUST
  • TOOLS & ECOSYSTEM
  • DEFINING FEATURES
  • WHERE TO START

WHY RUST

Rust is a systems  language that pursues the trifecta of:

  • speed

  • safety

  • concurrency

Speed

  • No Garbage Collection
  • LLVM
  • Zero cost abstractions
  • Minimal Runtime

Safety

  • Memory safety
  • Thread safety

out-of-bounds reads/writes, use-after-free, null pointer dereference and data races

Fearless Concurrency

  • Threads

  • Message Passing

  • Shared State

  • Extensible Concurrency

Beyond the trifecta

  • Cross-compilation

  • FFI Support

TOOLS & ECOSYSTEM

Compiler Toolchain

  • LLVM
  • Rustup
  • Rustc

Rustc & LLVM

..Rust is built on LLVM and strives to resemble Clang from LLVM’s perspective, any LLVM performance improvements also help Rust.

In the long run, the richer information in Rust’s type system should also enable optimizations that are difficult or impossible for C/C++ code

  • toolchain installer
  • cross-compilation tool
$ rustup install nightly
$ rustup default nightly
$ rustup target add arm-linux-androideabi
$ rustup override set nightly
$ rustup show

Package Management

Rust’s Package Manager, Build tool and test runner.

$ cargo new hello_world --bin

cargo new

$ cd hello_world
$ tree .
.
├── Cargo.toml
└── src
    └── main.rs

1 directory, 2 files

Cargo.toml

[package]
name = "hello_world"
version = "0.1.0"
authors = ["Matt Gathu <mattgathu@gmail.com>"]

src/main.rs

fn main() {
    println!("Hello, world!");
}

cargo build

$ cargo build
   Compiling hello_world v0.1.0 (file:../hello_world)
$ cargo run
     Fresh hello_world v0.1.0 (file:../hello_world)
   Running `target/hello_world`
Hello, world!

The Rust community’s crate registry.

~ 16,944 crates

IDEs Support

DEFINING FEATURES

Structs

struct Rectangle {
    width: i32,
    height: i32,
}

impl Rectangle {
    fn new(width: i32, height: i32) -> Rectangle {
         Rectangle { width, height}
    }
    
    fn area(&self) -> i32 {
        self.width * self.height
    }
}

fn main() {
    let rect = Rectangle::new(30, 50);

    println!("The area of rectangle is {}.", rect.area());
}

Traits

trait Shape {
    fn area(&self) -> f32;
}
impl Shape for Rectangle {
    fn area(&self) -> f32 {
        (self.width * self.height) as f32
    }
}

Generics

fn print_area<S: Shape+Debug>(shape: &S) {
    println!("The area of {:?} is {}", 
        shape, 
        shape.area());
}

Enums

enum Option<T> {
    Some(T),
    None,
}
pub fn is_some(&self) -> bool {
    match *self {
        Some(_) => true,
        None => false,
    }
}

Ownership Model

 

Memory is managed through a set of rules that the compiler checks at compile time.

 

Rules of Ownership

 
  • Each value has its owner.
  • There can only be one owner at a time.
  • When the owner goes out of scope, the value will be dropped.

 

fn as_str(data: &u32) -> &str {
    // compute the string
    let s = format!("{}", data);

    // (this does not compile in Rust)
    &s
}
// s goes out of scope and is freed here

A value cannot outlive its owner.

let mut data = vec![1, 2, 3];
// get an internal reference
let x = &data[0];

// (this does not compile in Rust)
data.push(4);

println!("{}", x);

A mutable value cannot be shared/aliased.

A mutable reference is aliased if there exists another live reference to one of its ancestors or descendants.

WHERE DO I START

Getting Started

curl https://sh.rustup.rs -sSf | sh

REFERENCES

RUST 101

By Matt Gathu

RUST 101

  • 1,169