[Rust] Borrow checker

发布时间 2023-05-29 14:47:31作者: Zhentiw

Three rules:

  1. There can only be one value owner
  2. There can be unlimited immutable borrows (reference) with no mutable references
  3. There can be only one mutable reference and no immuntable references

 

There is one rule for lifetimes

  1. A reference cannnot outlive its value

Example

#[derive(Debug)]
struct MyStruct {
  age: usize
}
fn main() {
   let mut items: Vec<&MyStruct> = vec![];
   {
       let item = MyStruct {age: 0};
       items.push(&item); // item does not live long enough borrowed ..
   }
    
   println!("{:?}", items); // borrow later used here
}

 

Stated differently

  • One var owns the data
  • One var can change the data
  • Many vars can look at the data
  • You cannot look and change the data simultaneously
  • You cannot refer to something that has been dropped (released in memory)

 

Example:

#[derive(Debug)]
struct Item {
    count: usize
}

fn add_one(mut item: Item) {
    item.count += 1;
}

fn main() {
    let item = Item {count: 1};
    println!("{:?}", item);
    add_one(item);
    println!("{:?}", item);
}

//  let item = Item {count: 1}; this line owns the item
//  add_one(items); move the ownership to add_one function
//  println!("{:?}", item); this line will cause error because item is moved to add_one function

 

Next step:

fn add_one(item: &Item) {
    item.count += 1;
}

// item.count += 1; not mutable

fn main() {
    let item = Item {count: 1};
    println!("{:?}", item);
    add_one(&item);
    println!("{:?}", item);
}

Now we pass the reference. But now get not mutable error

 

Next step:

fn add_one(item: &mut Item) {
    item.count += 1;
}

fn main() {
    let item = Item {count: 1};
    println!("{:?}", item);
    add_one(&item); // error, consider mutably borrowing here: `&mut item`
    println!("{:?}", item);
}

 

Next step:

fn add_one(item: &mut Item) {
    item.count += 1;
}

fn main() {
    let item = Item {count: 1};
    println!("{:?}", item);
    add_one(&mut item); // error: cannot borrow `item` as mutable, as it is not declared as mutable
    println!("{:?}", item);
}

 

Next step:

fn add_one(item: &mut Item) {
    item.count += 1;
}

fn main() {
    let mut item = Item {count: 1};
    println!("{:?}", item);
    add_one(&mut item); 
    println!("{:?}", item);
}