Slice : similar to array, but their length is unknown at compile time
Scoping rules
RAII
Ownership and moves resources can only have one owner. So traditional variable assignment can only be move or reference or copy.
Mutability: mutability can changes when the variable is moved to another owner.
1 2 3
let a = Box::new(2); letmut b = a; // move Box to b *b = 4; // it's ok.
Partial moves:
Borrowing
mutable data can be borrowed immutably
immutable data cannot be borrowed mutably
Ref pattern
In assignment:
1 2 3
let c:char = 'A'; letref a = c; let b = &c; // *a == *b
In pattern destructuion
1 2 3 4 5 6 7 8 9 10
let point = Point{x:2,y:4}; letmut mutable_point = point;
{ // `ref` can be paired with `mut` to take mutable references. let Point { x: _, y: refmut mut_ref_to_y } = mutable_point;
// Mutate the `y` field of `mutable_point` via a mutable reference. *mut_ref_to_y = 1; }
1 2 3 4 5 6
letmut mutable_tuple = (Box::new(5u32), 3u32); { // Destructure `mutable_tuple` to change the value of `last`. let (_, refmut last) = mutable_tuple; *last = 2u32; }
*const T - immutable raw pointer *mut T - mutable raw pointer
Both references and raw pointers can be created using & operator:
1 2 3 4 5 6 7
let x: u32 = 12;
let ref1: &u32 = &x; let raw1: *constu32 = &x;
let ref2: &mutu32 = &mut x; let raw2: *mutu32 = &mut x;
. automatically references or dereferences its left argument
1 2 3 4 5
structX { n: u32 };
impl X { fnmethod(&self) -> u32 { self.n } }
we don’t have to type (*self).method but using self.method instead.
Reference && Pointers
Main pointer kind used in rust should be references
Raw pointers, which don’t have restrictions or references, should be used in low-level code implementing high-level abstractions
Dynamically-sized (unsized) types
A fat pointer is basically a structure which contains the actual pointer to the piece of data and some additional information(length for slices, pointer to vtable for traits objects. Rust handles these details about pointer content transparently for the user.
Box<T>
can be borrowed
is equivalent to T
similar to built-in pointers, * to dereference
ref
ref is a syntax in patterns to obtain a variable of the reference type instead of a value
Case 1
1 2 3 4 5
let x: u32 = 12;
let y = x; // y: u32, a copy of x letref z = x; // z: &u32, points to x letrefmut zz = x; // zz: &mut u32, points to x
can be over rewritten with:
1 2
let z = &x; let zz = &mut x;
Case 2
1 2 3 4 5 6
let x: Option<Vec<u32>> = ...;
match x { Some(ref v) => ... None => ... }
x is only borrowed inside the whole match statement, which allows using x after this match
1 2 3 4
match x { Some(v) => ... None => ... }
if using this, part of x value are moved.
Some(v)
Some(&v)
Some(ref v)
move and copy
From Range to Vec
1 2 3
let v = (1..10).collect::<Vec<u32>>(); // or ?? let v:Vec<u32> = (1..10).collect();
pubfnpersonal_top_three(&self) -> Vec<u32> { letmut v:Vec<u32> = Vec::new(); // let mut i = 0; letmut tmp = self.v.clone(); tmp.sort(); for i in1..=3 { if tmp.len() < i { continue; } let val = tmp.get(tmp.len()-i).unwrap(); v.push(*val); } v } }
Things to do to simplify the code:
map Option<&T> to Option<T>
1 2
let v:Vec<i32> = Vec::new(); v.last().cloned() // ->Option<T>