As you arrive

On a post it note write a reason why you're interested in learning Rust.

Stick the note on the whiteboard.

mscroggs.github.io/rust-intro

An introduction to Rust

Matthew Scroggs

Plan for today

  1. Hello world
  2. Basic Rust syntax
  3. Testing in Rust
  4. Traits and structs
  5. Reasons to like Rust
An introduction to Rust (mscroggs.github.io/rust-intro)

Getting started

  • In terminal:
    • cargo init
    • cargo run
  • Can instead do cargo init --lib to initialise a library
An introduction to Rust (mscroggs.github.io/rust-intro)

Getting started

  • cargo init creates:
    • Cargo.toml
      • You can add dependencies to this file
    • src/main.rs with Hello World code in it
    • By default, it also initialises a git repo in your folder, creating .git/ and .gitignore
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax

An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #1: variables

let n = 5;
println!("n is {n}");
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #1: variables

Note: all variables are constant by default. This will give a compiler error:

let n = 5;
n += 1;
println!("n is {n}");

Instead, you must use the mut keyword to make the variable mutable:

let mut n = 5;
n += 1;
println!("n is {n}");
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #2: if, else

if sides == 1 {
    panic!("A polygon cannot have 1 side");
} else if sides == 2 {
    panic!("A polygon cannot have 2 sides");
} else {
    println!("Creating a polygon with {sides} sides")
}
  • No () around conditions (like Python)
  • {} around code blocks and ; at ends of lines (like C++)
  • Indentation is for style (unlike Python
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #3: functions

You can do either:

fn one_more(n: int) -> int {
    return n + 1;
}

Or:

fn one_more(n: int) -> int {
    n + 1
}

When making a library, the keyword pub can be used before fn to define public functions.

An introduction to Rust (mscroggs.github.io/rust-intro)

Activity

Write a function that takes the number of sides as an input and returns the size
of an an angle in a regular polygon with that number of sides.


Hint: f64 and f32 are the Rust types for 64 and 32 bit floats

An introduction to Rust (mscroggs.github.io/rust-intro)

Testing in Rust

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

then run cargo test

  • #[cfg(test)] means the mod will only be compiled if running cargo test
  • Any function marked with #[test] will be run by cargo test
An introduction to Rust (mscroggs.github.io/rust-intro)

Activity

Add a test that checks the output of your angle function.


You may want to:

  • Add approx = "0.5" as a dependency
  • Add use approx::*; at the start of your tests
  • Use assert_relative_eq!(a, b); to assert that two values are close
    • assert_relative_eq!(a, b, epsilon=1e-8); to adjust tolerance
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #4: loops

  • while loop:
    while condition {
        println!("Print this");
    }
    
  • for loop:
    for n in 0..5 {
        println!("The next number is {n}")
    }
    
    
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #4: loops

  • loop loops forever:
    loop {
        println!("Still going...");
    }
    
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #5: Vec

  • A Vec is similar to a Python list. They can be created using vec!:
    let ten_zeros = vec![0.0; 10];
    println!("{ten_zeros:?}");
    let mut odds = vec![1, 3, 5, 7, 9];
    println!("{odds:?}");
    
  • [] can be used to get an item:
    println!("{}", odds[1]);
    
  • push adds an item to the end of a Vec:
    odds.push(11);
    println!("{odds:?}");
    
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #5: Vec

  • Functions can return a Vec:
    fn f(number_of_zeros: usize) -> Vec<f64> {
        vec![0.0; number_of_zeros];
    }
    
An introduction to Rust (mscroggs.github.io/rust-intro)

Basic syntax #5: Maths functions

  • The f32 and f64 types support lots of common functions:
    let angle = 2.0;
    println!("{}", f64::sin(angle));
    println!("{}", angle.sin());
    
    println!("{}", f32::sqrt(2.0));
    println!("{}", f64::sqrt(2.0));
    
    println!("{}", std::f64::consts::PI);
    
An introduction to Rust (mscroggs.github.io/rust-intro)

Activity

Write a function that takes the number of sides as an input and the coordinates
of the vertices of a regular polygon with that number of sides.

An introduction to Rust (mscroggs.github.io/rust-intro)

Probably a good time for a break

... I hope I remembered to make cake

An introduction to Rust (mscroggs.github.io/rust-intro)

traits

A trait is use to define an abstract interface that could be implemented. For example:

/// Any polygon
trait Polygon {
    /// Number of vertices
    fn vertex_count(&self) -> int;

    /// The area of the polygon
    fn area(&self) -> f64;

    /// The perimeter of the polygon
    fn perimeter(&self) -> f64;
}
An introduction to Rust (mscroggs.github.io/rust-intro)

structs

A struct can be used to store data of a mixture of types.

/// A regular polygon
struct RegularPolygon {
    /// Number of sides
    n_sides: int,
}


let triangle = RegularPolygon { n_sides: 3 };
An introduction to Rust (mscroggs.github.io/rust-intro)

structs

Functions can be implemented for a struct. The function new is often defined to make a nicer user interface:

impl RegularPolygon {
    /// Create a new
    pub fn new(number_of_sides: int) -> Self {
        Self { n_sides: number_of_sides }
    }
}


let triangle = RegularPolygon::new(3);
An introduction to Rust (mscroggs.github.io/rust-intro)

structs

When initialising a struct variable: variable can be simplified to just variable, eg:

impl RegularPolygon {
    /// Create a new
    pub fn new(n_sides: int) -> Self {
        Self { n_sides }
    }
}
An introduction to Rust (mscroggs.github.io/rust-intro)

structs

Traits can be implemented for a struct:

impl Polygon for RegularPolygon {
    fn vertex_count(&self) -> usize {
        self.n_sides
    }
    fn area(&self) -> f64 {
        todo!();
    }
    fn perimeter(&self) -> f64 {
        todo!();
    }
}
An introduction to Rust (mscroggs.github.io/rust-intro)

Activity

Finish implementing the Polygon trait for RegularPolygon:

impl Polygon for RegularPolygon {
    fn vertex_count(&self) -> usize {
        self.n_sides
    }
    fn area(&self) -> f64 {
        todo!();
    }
    fn perimeter(&self) -> f64 {
        todo!();
    }
}

... then test it!

An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust

An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #1: &impl Trait

Functions can use "any item that implements this trait" as an input type:

struct Prism {
}

fn make_prism(&impl Polygon) -> Prism {
    todo!();
}

This means your function can be used for objects in someone else's library as long as the other person has implemented your Polygon trait.

An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #2: package management

Adding dependencies is easy (Cargo.toml):

[dependencies]
quadraturerules = "0.9.0"
itertools = "0.14.*"
rlst = { version = "0.6" }
mpi = { version = "0.8.0", optional = true }
serde = { version = "1", features = ["derive"], optional = true }

cargo publish can be used to make your crate available on crates.io.

An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #3: Any code block can return a value

let n_points = if degree < 2 {
    0
} else {
    degree - 2
};
fn collatz(n: int) -> int {
    if n % 2 == 0 {
        n / 2
    } else {
        3 * n + 1
    }
}
An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #4: enums can hold values

pub enum Transformation {
    /// An identity transformation
    Identity,
    /// A permutation
    Permutation(Vec<usize>),
}
An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #5: if let

let t = Transformation::Identity;

if let Permutation(p) = t {
    todo!();
}
An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #6: break 'a

' can used to label a loop then tell break which loop to break.

'a: for i in 2..100 {
    for j in 2..100 {
        if i * j == 56 {
            println!("{i} {j}");
            break 'a;
        }
    }
}
An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #7: Borrowing

Every item in Rust has an owner. If an item is passed into a function, the function takes ownership

let a = vec![0, 1];
function(a);

// This will cause a compiler error
println!("{:?}", a);
An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #7: Borrowing

& can be used to "borrow" items to let a function use them without taking ownership:

let a = vec![0, 1];
function(&a);

// This will NOT cause a compiler error
println!("{:?}", a);

&mut can be used to let functions have a mutable borrow.

An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #8: Memory safety

The compiler checks that at any time, any item has either:

  • one mutable borrow
  • one or more non-mutable borrow

This is an important part of how the compiler enforces memory safety.

An introduction to Rust (mscroggs.github.io/rust-intro)

Reasons to like Rust #9: cargo fmt and cargo clippy

  • Code formatting and linting out of the box
An introduction to Rust (mscroggs.github.io/rust-intro)

Where to learn more

An introduction to Rust (mscroggs.github.io/rust-intro)

Feedback and conclusions

  • One post it notes, write:
    • One thing that you learned today
    • How this session has affected your desire to learn Rust
    • Any suggestions for next time I run something like this, eg:
      • anything that was unclear
      • anything that we didn't cover that you'd like to have seen
      • anything that we spent too long on
    • Any suggestions for follow on events if you want to do more Rust
An introduction to Rust (mscroggs.github.io/rust-intro)

Thanks for coming!

mscroggs.github.io/rust-intro

An introduction to Rust (mscroggs.github.io/rust-intro)