Intro To Rust
Intro To Rust
Introduction to Rust
CSE 333 Autumn 2023
Lecture Outline
❖ A (very brief) tour of Rust
▪ Not comprehensive, but will highlight interesting features
▪ Basic examples directly from “The Book” and “Rust by Example”
▪ Resources to learn Rust listed on last slide
2
L28: Intro to Rust CSE333, Autumn 2023
Logistics
❖ Ex12 due tonight
❖ Exam prep
3
L28: Intro to Rust CSE333, Autumn 2023
What is Rust?
❖ Rust is a modern systems programming language focusing
on safety, speed, and concurrency. It accomplishes these
goals by being memory safe without using garbage
collection.
– Rust By Example
4
L28: Intro to Rust CSE333, Autumn 2023
Rust
❖ Characteristics
▪ Aims to support efficient, fearless, concurrent systems programming
▪ Memory safe with rich type system
▪ Ergonomic developer experience
▪ Interoperable with C/C++
5
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
println!("Hello, World!");
}
fn main() {
let unit = "CSE";
let course_num: u16 = 333;
let term = String::from("Autumn 2023");
$ rustc hello_cse333.rs
$ ./hello_cse333
Hello CSE 333, Autumn 2023 edition
6
L28: Intro to Rust CSE333, Autumn 2023
Scalar Types
● signed integers: i8, i16, i32, i64, i128 and isize (pointer size)
● unsigned integers: u8, u16, u32, u64, u128 and usize (pointer size)
● floating point: f32, f64
● char Unicode scalar values like 'a', 'α' and '∞' (4 bytes each)
● bool either true or false
● and the unit type (), whose only possible value is an empty tuple: ()
fn main() {
// Variables can be type annotated.
let logical: bool = true;
7
L28: Intro to Rust CSE333, Autumn 2023
Compound Types
● arrays like [1, 2, 3]
● tuples like (1, true)
Mutability
● Variables are immutable by default.
fn main() {
let num = 333;
let mut year = 2021;
Structures (3 types)
// A unit struct
struct Unit;
● Tuple structs: named tuples
// A tuple struct
● Classic C structs struct Pair(i32, f32);
fn main() {
// Instantiate a unit struct
let _unit = Unit;
// Instantiate a tuple struct
let pair = Pair(1, 0.1);
// Instantiate a C struct
let point = Point { x: 333, y: 2022 };
// Access `y` field of `point`.
let year = point.y;
}
9
L28: Intro to Rust CSE333, Autumn 2023
Functions
● declared using the fn keyword
● arguments are type annotated
● if the function returns a value, the return type must be specified after an arrow ->
fn main() {
let x = plus_one(5);
10
L28: Intro to Rust CSE333, Autumn 2023
if / else
● boolean condition doesn't need to be surrounded by parentheses
● each condition is followed by a block
● if-else conditionals are expressions, and, all branches must return the same type
fn main() {
let n = 5;
if n < 0 {
print!("{} is negative", n);
} else if n > 0 {
print!("{} is positive", n);
} else {
print!("{} is zero", n);
}
}
11
L28: Intro to Rust CSE333, Autumn 2023
if / else (cont’d)
● boolean condition doesn't need to be surrounded by parentheses
● each condition is followed by a block
● if-else conditionals are expressions, and, all branches must return the same type
fn main() {
let n = 5;
12
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
while // A counter variable
let mut n = 1;
● loop while condition is true
// Loop while `n` is less than 101
● → FizzBuzz
while n < 101 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
// Increment counter
n += 1;
}
}
13
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
for-in // `n` will take the values:
// 1, 2, ..., 100
● for traverses an iterator for n in 1..101 {
if n % 15 == 0 {
● → FizzBuzz with for-in println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
}
}
● create iterator and traverse
fn main() {
let names = vec!["Alice", "Frank", "Ferris"];
match
● powerful pattern matching
● first matching arm is evaluated
● all possible values must be covered
fn main() {
let number = 13;
match number {
// Match a single value
1 => println!("One!"),
// Match several values
2 | 3 | 5 | 7 | 11 => println!("This is a small prime"),
// Match an inclusive range
13..=19 => println!("A teen"),
// Handle the rest of cases
_ => println!("Ain't special"),
}
}
15
L28: Intro to Rust CSE333, Autumn 2023
struct Point {
x: f64,
y: f64,
}
16
L28: Intro to Rust CSE333, Autumn 2023
x 333
stack
17
L28: Intro to Rust CSE333, Autumn 2023
x 333
stack
18
L28: Intro to Rust CSE333, Autumn 2023
y 351
// `w` variable is a reference that holds
// a pointer value x 333
let w = &x;
stack
19
L28: Intro to Rust CSE333, Autumn 2023
y 351
// `w` variable is a reference that holds
// a pointer value x 333
let w = &x;
stack
// `z` initially has same value as `w`
let mut z = &x;
20
L28: Intro to Rust CSE333, Autumn 2023
y 351
// `w` variable is a reference that holds
// a pointer value x 333
let w = &x;
stack
// `z` initially has same value as `w`
let mut z = &x;
// … but its value is mutable
z = &y;
21
L28: Intro to Rust CSE333, Autumn 2023
borrow
checker
22
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333); // position t1
double_value(x);
x 333 …
stack heap 23
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333);
double_value(x); No!
}
24
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(mut x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333);
double_value(x);
25
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(mut x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333);
double_value(x); Yes!
}
26
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(mut x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
27
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
x 333 …
stack heap 28
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
ownership moved, original x is no longer accessible since it does not contain a value
x
(double_value)
..
.
x 333 …
stack heap 29
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
x
(double_value)
..
.
666 …
stack heap 30
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
..
.
…
stack heap 31
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
stack heap 32
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(mut x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333);
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
Recall
▪ Each value in Rust has an owner
▪ There can only be one owner at a time
▪ When the owner goes out of scope, the value is dropped
33
L28: Intro to Rust CSE333, Autumn 2023
fn double_value(mut x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?
fn main() {
let mut x = Box::new(333);
double_value(x); No!
println!("What happens if I take 333 twice?: {}", x);
}
34
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333;
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
35
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333; Yes!
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
36
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333; Yes!
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
BUT…
37
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333; Yes!
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
38
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333; Yes!
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
x 333
(double_value)
..
.
x 333
(main)
stack 39
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333; Yes!
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
x 666
(double_value)
..
.
x 333
(main)
stack 40
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
let mut x = 333; Yes!
double_value(x);
println!("What happens if I take 333 twice?: {}", x);
}
x 333
(main)
stack 41
L28: Intro to Rust CSE333, Autumn 2023
Borrowing
❖ References “borrow” a value, but never take ownership
❖ Can have shared references (&T),
or mutable references (&mut T)
fn❖double_value(x: &mut i32) {
*x = 2 * (*x); Does this compile?
❖
}
fn main() {
let mut x = 333;
double_value(&mut x);
println!("What happens if I take 333 twice?: {}", x);
}
x
(double_value)
..
$ rustc
. ownership_copy.rs
x $ ./ownership_copy
666
(main)
Borrowing
❖ References “borrow” a value, but never take ownership
❖ Can have shared references (&T),
or mutable references (&mut T)
fn❖double_value(x: &mut i32) {
*x = 2 * (*x); Does this compile?
❖
}
fn main() {
let mut x = 333;
double_value(&mut x);
println!("What happens if I take 333 twice?: {}", x);
}
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
43
L28: Intro to Rust CSE333, Autumn 2023
Borrowing
❖ References “borrow” a value, but never take ownership
❖ Can have shared references (&T),
or mutable references (&mut T)
fn❖double_value(x: &mut i32) {
*x = 2 * (*x); Does this compile?
❖
}
fn main() {
let mut x = 333;
double_value(&mut x);
println!("What happens if I take 333 twice?: {}", x);
}
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
44
L28: Intro to Rust CSE333, Autumn 2023
Borrowing
❖ References “borrow” a value, but never take ownership
❖ Can have shared references (&T),
or mutable references (&mut T)
fn❖double_value(x: &mut i32) {
*x = 2 * (*x); Does this compile?
❖
}
fn main() {
let mut x = 333; Yes!
double_value(&mut x);
println!("What happens if I take 333 twice?: {}", x);
}
$ rustc ownership_borrow.rs
ownership_copy.rs
$ ./ownership_borrow
./ownership_copy
What happens if I take 333 twice?: 666
333
45
L28: Intro to Rust CSE333, Autumn 2023
Borrowing rules
❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
46
L28: Intro to Rust CSE333, Autumn 2023
Borrowing rules
❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
47
L28: Intro to Rust CSE333, Autumn 2023
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
48
L28: Intro to Rust CSE333, Autumn 2023
$ |./ownership_copy
-- immutable borrow occurs here
5 | let r2 = &x;
What happens
6 | let r3 = &mut x; if I take 333 twice?: 333
| ^^^^^^ mutable borrow occurs here
7 | println!("{}", r1);
| -- immutable borrow later used here
49
L28: Intro to Rust CSE333, Autumn 2023
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
50
L28: Intro to Rust CSE333, Autumn 2023
borrow
checker
https://hacks.mozilla.org/2018/12/rust-2018-is-here/
51
L28: Intro to Rust CSE333, Autumn 2023
borrow
checker
https://hacks.mozilla.org/2018/12/rust-2018-is-here/
(*) This isn’t always true. The borrow checker remains conservative when safety is on the line.
52
L28: Intro to Rust CSE333, Autumn 2023
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
53
L28: Intro to Rust CSE333, Autumn 2023
54
L28: Intro to Rust CSE333, Autumn 2023
55
L28: Intro to Rust CSE333, Autumn 2023
56
L28: Intro to Rust CSE333, Autumn 2023
let r1 = &x;
‘a
*x = 351;
‘a println!("{}", r1);
57
L28: Intro to Rust CSE333, Autumn 2023
fn main() {
// x 'owns' the heap allocated string below
let x = String::from("CSE 333");
58
L28: Intro to Rust CSE333, Autumn 2023
60
L28: Intro to Rust CSE333, Autumn 2023
61
L28: Intro to Rust CSE333, Autumn 2023
Rust Resources
❖ Rust Programming Language website:
https://www.rust-lang.org/
62
L28: Intro to Rust CSE333, Autumn 2023
https://hacks.mozilla.org/2018/12/rust-2018-is-here/
63
L28: Intro to Rust CSE333, Autumn 2023
Lecture Outline
❖ A (very brief) tour of Rust
▪ Not comprehensive, but will highlight interesting features
▪ Basic examples directly from “The Book” and “Rust by Example”
▪ Resources to learn Rust listed on last slide
64