0% found this document useful (0 votes)
20 views64 pages

Intro To Rust

Uploaded by

tien.tadinh1609
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views64 pages

Intro To Rust

Uploaded by

tien.tadinh1609
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 64

L28: Intro to Rust CSE333, Autumn 2023

Introduction to Rust
CSE 333 Autumn 2023

Lecturer: Chris Thachuk


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

❖ Demo project: designing orthogonal strands of DNA

2
L28: Intro to Rust CSE333, Autumn 2023

Logistics
❖ Ex12 due tonight

❖ Hw4 due Wednesday (12/4)

❖ Section this week (course wrap-up)

❖ Last bonus lecture today; no lectures on Wed & Fri

❖ 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

❖ Rust programmers are called ‘Rustaceans’

4
L28: Intro to Rust CSE333, Autumn 2023

Rust

❖ Created in 2006 by Graydon Hoare


▪ Sponsored by Mozilla in 2009
▪ Multi-paradigm, general purpose programming language
▪ Adopted by major companies and governance via Rust Foundation
▪ Rust will become the second ‘main’ language in Linux Kernel 6.1

❖ 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

Hello World in Rust

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

fn main() {
let unit = "CSE";
let course_num: u16 = 333;
let term = String::from("Autumn 2023");

println!("Hello {} {}, {} edition", unit, course_num, term);


}
hello_cse333.rs

$ 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;

let a_float: f64 = 1.0; // Regular annotation


let an_integer = 5i32; // Suffix annotation

// A type can also be inferred from context


let mut inferred_type = 333; // Type i64 is inferred from another line
inferred_type = 3333333333i64;
}

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;

// The value of a mutable variable can change.


year = 2022;

// Error! The type of a variable can't be changed.


year = true;

// Error! Variables are immutable by default.


num = 351;
}
8
L28: Intro to Rust CSE333, Autumn 2023

Structures (3 types)
// A unit struct
struct Unit;
● Tuple structs: named tuples
// A tuple struct
● Classic C structs struct Pair(i32, f32);

● Unit structs: field-less // A struct with two fields


struct Point {
(useful for generics) x: f32,
y: 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);

println!("The value of x is: {}", x);


}

fn plus_one(x: i32) -> i32 {


x + 1
}

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;

let big_n = if n < 10 && n > -10 {


println!("{} is a small number, increase ten-fold", n);
// This expression returns an `i32`.
10 * n
} else {
println!("{} is a big number, halve the number");
// This expression must return an `i32` as well.
n / 2
};
// ^ Don't forget to put a semicolon here! All `let` bindings need it.
println!("{} -> {}", n, big_n);
}

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"];

for name in names.iter() {


println!("Hello {}", name),
}
}
14
L28: Intro to Rust CSE333, Autumn 2023

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

Associated functions & methods


● associated functions are functions that are defined on a type
● methods are associated functions that are called on a particular instance of a type

struct Point {
x: f64,
y: f64,
}

// Implementation block, all `Point` associated functions & methods go in here


impl Point {
// An associated function, taking two arguments:
fn new(x: f64, y: f64) -> Point {
Point { x: x, y: y }
}
// This method requires the caller object to be mutable
fn translate(&mut self, x: f64, y: f64) {
self.x += x;
self.y += y;
}
}

16
L28: Intro to Rust CSE333, Autumn 2023

Values, variables, and pointers


❖ values are stored in a place
❖ a place is a location that can hold a value
❖ e.g. on the stack, on the heap, etc
❖ a variable is named location on the stack

// `x` variable is a named place on stack


let x = 333; // x holds the i32 value ‘333’

x 333

stack

17
L28: Intro to Rust CSE333, Autumn 2023

Values, variables, and pointers


❖ values are stored in a place
❖ a place is a location that can hold a value
❖ e.g. on the stack, on the heap, etc
❖ a variable is named location on the stack

// `x` variable is a named place on stack


let x = 333; // x holds the i32 value ‘333’
let y = 351;
y 351

x 333

stack

18
L28: Intro to Rust CSE333, Autumn 2023

Values, variables, and pointers


❖ values are stored in a place
❖ a place is a location that can hold a value
❖ e.g. on the stack, on the heap, etc
❖ a variable is named location on the stack
❖ a pointer holds the address of a place
// `x` variable is a named place on stack
let x = 333; // x holds the i32 value ‘333’
let y = 351; w

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

Values, variables, and pointers


❖ values are stored in a place
❖ a place is a location that can hold a value
❖ e.g. on the stack, on the heap, etc
❖ a variable is named location on the stack
❖ a pointer holds the address of a place
// `x` variable is a named place on stack z
let x = 333; // x holds the i32 value ‘333’
let y = 351; w

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

Values, variables, and pointers


❖ values are stored in a place
❖ a place is a location that can hold a value
❖ e.g. on the stack, on the heap, etc
❖ a variable is named location on the stack
❖ a pointer holds the address of a place
// `x` variable is a named place on stack z
let x = 333; // x holds the i32 value ‘333’
let y = 351; w

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

Ownership (Rust’s secret sauce)


❖ Ownership Rules:
▪ 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

borrow
checker

22
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap

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);

// memory relationships at position t1

x 333 …

stack heap 23
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap

fn double_value(x: Box<i32>) {
*x = 2 * (*x);
} Does this compile?

fn main() {
let mut x = Box::new(333);
double_value(x); No!
}

error[E0594]: cannot assign to `*x`, as `x` is not declared as mutable


--> src/main.rs:3:5
|
2 | fn double_value(x: Box<i32>) {
| - help: consider changing this to be mutable: `mut x`
3 | *x = 2 * (*x);
| ^^^^^^^^^^^^^ cannot assign

24
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap

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

Ownership and moves


❖ note: box is a place we create on the heap

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

Ownership and moves


❖ note: box is a place we create on the heap

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

Ownership and moves


❖ note: box is a place we create on the heap
❖ what owns the value ‘333’?
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);
}

x 333 …

stack heap 28
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap
❖ what owns the value ‘333’?
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);
}

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

Ownership and moves


❖ note: box is a place we create on the heap
❖ what owns the value ‘333’?
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);
}

x
(double_value)

..
.
666 …

stack heap 30
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap
❖ what owns the value ‘333’?
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);
}

x owner out of scope ⇒ value is dropped


(double_value)

..
.

stack heap 31
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap
❖ what owns the value ‘333’?
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);
}

stack heap 32
L28: Intro to Rust CSE333, Autumn 2023

Ownership and moves


❖ note: box is a place we create on the heap

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

Ownership and moves


❖ note: box is a place we create on the heap

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);
}

error[E0382]: borrow of moved value: `x`


--> src/main.rs:9:55
|
7 | let mut x = Box::new(333);
| ----- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
8 | double_value(x);
| - value moved here
9 | println!("What happens if I take 333 twice?: {}", x);
| ^ value borrowed here after move

34
L28: Intro to Rust CSE333, Autumn 2023

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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

Ownership and `Copy` trait


❖ To “be Copy” means a type’s value can be duplicated
by copying its bit representation
❖ Most primitive types “are Copy”
fn double_value(mut x: i32) {
x = 2 * x; Does this compile?
}

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)

What happens if I take 333 twice?: 333


stack 42
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
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

let mut x = Box::new(333);


let r1 = &x; Does this compile?
let r2 = &x;
println!("{}", r1);

$ 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

let mut x = Box::new(333);


let r1 = &x; Does this compile?
let r2 = &x;
println!("{}", r1);
Yes!

$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
47
L28: Intro to Rust CSE333, Autumn 2023

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; Does this compile?
let r2 = &x;
let r3 = &mut x;
println!("{}", r1);

$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333
48
L28: Intro to Rust CSE333, Autumn 2023

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; Does this compile?
let r2 = &x;
let r3 = &mut x;
println!("{}", r1); No!

error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable


--> src/main.rs:6:10
|
$4 |rustc ownership_copy.rs
let r1 = &x;

$ |./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

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; Does this compile?
let r2 = &x;
println!("{}", r1);
let r3 = &mut x;

$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333

50
L28: Intro to Rust CSE333, Autumn 2023

Pre 2018 borrow checking (lexical lifetimes)


❖ borrow checking used to be lexically scoped
❖ confusing to new Rustaceans (this code seems correct)

borrow
checker

https://hacks.mozilla.org/2018/12/rust-2018-is-here/
51
L28: Intro to Rust CSE333, Autumn 2023

Borrow checking (non-lexical lifetimes)


❖ lifetimes end after use (not end of block)
❖ code that you reason should compile, will (*)

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

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; Does this compile?
let r2 = &x;
println!("{}", r1);
let r3 = &mut x; Yes!

$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333

53
L28: Intro to Rust CSE333, Autumn 2023

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; Does this compile?
if rand() < 0.333 {
*x = 351;
} else {
println!("{}", r1);
}
println!("{}", r1);
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333

54
L28: Intro to Rust CSE333, Autumn 2023

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; // lifetime 'a Does this compile?
if rand() < 0.333 { // |
*x = 351; // |
} else { // |
println!("{}", r1); // |
} // |
println!("{}", r1); //-/
$ rustc ownership_copy.rs
$ ./ownership_copy
What happens if I take 333 twice?: 333

55
L28: Intro to Rust CSE333, Autumn 2023

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; Does this compile?
if rand() < 0.333 {
*x = 351;
} else {
println!("{}", r1);
}

56
L28: Intro to Rust CSE333, Autumn 2023

Borrowing rules and lifetimes


❖ Can have multiple shared references simultaneously
❖ A mutable reference is an exclusive borrow

let mut x = Box::new(333);


let r1 = &x; // lifetime 'a Does this compile?
if rand() < 0.333 {
*x = 351;
} else { Yes!
println!("{}", r1); // lifetime 'a
}

let r1 = &x;

‘a

*x = 351;
‘a println!("{}", r1);
57
L28: Intro to Rust CSE333, Autumn 2023

Memory safety by examples

fn main() {
// x 'owns' the heap allocated string below
let x = String::from("CSE 333");

// y took over ownership here (i.e., ownership "moved")


let y = x;

// x no longer owns value resulting in a borrow error


println!("Hello, {}", x);
}

58
L28: Intro to Rust CSE333, Autumn 2023

Memory safety by examples (cont’d)

Is this code OK? → fn main() {


let x = String::from("CSE 333");

let y = &x; // Immutable borrow

println!("Hello, {}", x);


println!("Goodbye, {}", y);
}

Is this code OK? →


fn main() {
let y = {
let x = String::from("hi");
&x
};
println!("{}", y);
}
59
L28: Intro to Rust CSE333, Autumn 2023

Rust memory safety

● Either one mutable reference OR many immutable references


● No null
● Out-of-bounds access (checked at runtime) results in program panic
● Ownership rules apply across multiple threads
(no data races across threads, checked at compile time)

● Is memory leaking safe?

60
L28: Intro to Rust CSE333, Autumn 2023

Rust memory safety

● Either one mutable reference OR many immutable references


● No null
● Out-of-bounds access (checked at runtime) results in program panic
● Ownership rules apply across multiple threads
(no data races across threads, checked at compile time)

● Is memory leaking safe?


smart pointers
● Box<T> for allocating values on the heap
● Rc<T>, a reference counting type that enables multiple ownership
● Ref<T> and RefMut<T>, accessed through RefCell<T>, a type that enforces the
borrowing rules at runtime instead of compile time

61
L28: Intro to Rust CSE333, Autumn 2023

Rust Resources
❖ Rust Programming Language website:
https://www.rust-lang.org/

❖ “The Book” (official book):


https://doc.rust-lang.org/book/

❖ Rust for Rustaceans (intermediate book):


https://rust-for-rustaceans.com/

❖ Crates.io (official package repository):


https://crates.io/

62
L28: Intro to Rust CSE333, Autumn 2023

Rust code can compile to WebAssembly


❖ code would run in client’s browser (i.e. serverless)

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

❖ Demo project: designing orthogonal strands of DNA

64

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy