Download - Tour of Rust
Tour of Rust
Seo Sanghyeon2016-08-18
Control and Safety• C++
More control, less safety• Java
Less control, more safety• Rust
More control, more safety
Users• Rust
Rust compiler is written in Rust• Servo
Parallel browser engine• Dropbox
Cloud file storage• More on
https://www.rust-lang.org/en-US/friends.html
Memory representation
struct Point { x: i32, y: i32 }
struct Size { width: i32, height: i32 }
struct Rect { origin: Point, size: Size }
Boxed representation
xy
widthheight
originsize
rect
Unboxed representation
xy
widthheight
Assignment• b = a, by default,
Reference in PythonCopy in C++Move in Rust
Reference (Python)a = [1, 2, 3]b = aa[2] = 4b[2] # evaluates to 4
Reference
1 2 3a
b
4
Copy (C++)std::vector<int> a, b;a = {1, 2, 3};b = a;a[2] = 4;b[2]; // evaluates to 3
Copy
1 2 3a
b 1 2 3
4
Copy (C++) and destructionstd::vector<int> a, b;a = {1, 2, 3};b = a;// b is destroyed// a is destroyed
Move (Rust) and destructionlet a = vec![1, 2, 3];let b = a;// a is moved and can’t be used// any more// b is destroyed// a is not destroyed
Move
1 2 3a
b
Comparison
Python C++ Rust
Reference b = a T& b = a b = &a
Copy b = list(a) b = a b = a.clone()
Move b = move(a) b = a
Move (C++)std::vector<int> a, b;a = {1, 2, 3};b = std::move(a);a[2] = 4; // crashes
Move (Rust), 1let a = vec![1, 2, 3];let b = a;a[2] = 4;
Immutable by default| let a = vec![1, 2, 3];| - use `mut a` here| let b = a;| a[2] = 4;| ^ cannot borrow mutably
Move (Rust), 2let mut a = vec![1, 2, 3];let b = a;a[2] = 4;
Move is enforced| let b = a;| - value moved here| a[2] = 4;| ^ value used here after move
Conditional movelet a = vec![1, 2, 3];if random() { let b = a;}// is a destroyed?
Move flaglet a = vec![1, 2, 3];let a_flag = true;if random() { let a_flag = false; let b = a;}if a_flag { /* a is destroyed */ }
Move based on type• In Rust, b = a
Move by defaultCopy if a: T and T: Copy
Copy is opt-instruct Point { x: i32, y: i32,}
impl Copy for Point {}
Copy impl is checkedstruct Point { name: String, x: i32, y: i32,}
impl Copy for Point {}// error: field `name` does not implement Copy
Copy for references• &T: Copy
Immutable reference is copied• &mut T: !Copy
Mutable reference cannot be copied
Invalidation (C++)std::vector<int> a;a.push_back(1);int& b = a[0];a.push_back(2);b; // undefined
Invalidation (Rust)let mut a = vec![];a.push(1);let b = &a[0];a.push(2);
Compile time check| let b = &a[0];| - immutable borrow| a.push(2);| ^ mutable borrow
Borrow is scopedlet mut a = vec![];a.push(1);{ let b = &a[0]; b; // this is okay!}a.push(2); // this too!
Aliasing XOR Mutation• Multiple immutable borrows• Or single mutable borrow
• This is why &mut T cannot be copied
Functionfn get(v: &Vec<i32>, i: usize) -> &i32 { &v[i] }
let mut a = vec![];a.push(1);let b = get(&a, 0);a.push(2);
Lifetimefn get<’a>(v: &’a Vec<i32>, i: usize) -> &’a i32 { &v[i] }
let mut a = vec![];a.push(1);let b = get(&a, 0);a.push(2);
Lifetime subtyping• If ’a: ’b (’a outlives ’b)
&’a T <: &’b T
• Converse is also true:If &’a T <: &’b T’a: ’b
Lifetime inferencefn get<’a>(v: &’a Vec<i32>, i: usize) -> &’a i32 { &v[i] }
let b: &’x i32 = get(&’y a, 0);// what is relationship between// ’x and ’y?
Inference steps• fn get <: get• &’a T -> &’a U <: &’y T -> &’x U• &’y T <: &’a T, &’a U <: &’x U• ’y: ’a, ’a: ’x• ’y: ’x
Lifetime inference resultlet b: &’x i32 = get(&’y a, 0);// ’y outlives ’x// a is borrowed as long as// b is in scope// which was to be demonstrated