本文最后更新于 2024-03-29,本文发布时间距今超过 90 天, 文章内容可能已经过时。最新内容请以官方内容为准

Rust Study Day3

1. borrowing & ownership

The borrowing rule are simple:

[1]-Two or more pointers access the same data at the same time.
[2]-At least one of the pointers is being used to write to the data.
[3]-There’s no mechanism being used to synchronize access to the data.

Let’s less talking but more code and explanation.


    // borrowing and reference
    let mut a1 = String::from("I'm a1"); // make a1 is mutable
    let b1 = &a1; // borrowing
    let b2 = &a1; // borrowing
                  //let b3 = &mut a1; // trying to borrow a1 and modify it, but it's not allowed at here due to the rule of languaage.
                  // b1 and b2 are borrow a1 as a immutable type, so we cannot borrow it as a mutable type currently.
    println!(
        "b1 and b2 value should same as a1, due to there are point the a1 address.\nb1: {}\n b2: {}\n",
        b1, b2
    );

    // But b3 can borrow a1 and modify it here, due to the b1/b2 borrowing scope is end of above,
    // and b1/b2 are not used after.
    let b3 = &mut a1;
    b3.push_str(", and i was modified by b3.");
    println!("a1 now is :{}", a1);

The Terminal output:

b1 and b2 value should same as a1, due to there are point the a1 address.

b1: I’m a1

b2: I’m a1

a1 now is :I’m a1, and i was modified by b3.

Advantages:

  1. Avoiding resource competition.
  2. Avoiding dangling pointers.

2. Dangling References

Dangling in Chinese means 悬空。

Why is it called dangling[悬空]?

  • Reference to nothing, so it’s called dangling.

The Rules of References
Let’s recap what we’ve discussed about references:

[1].At any given time, you can have either one mutable reference or any number of immutable references.
[2].References must always be valid.

fn main() {
    let reference_to_nothing = dangle();
}

fn dangle() -> &String // dangle returns a reference to a String
{
    let s = String::from("hello");

    &s // A reference to the String of s is returned
} // Here, s goes out of scope, and is dropped. Its memory goes away.
  // Danger!

Due to the rules of references, the code above is illegal.

Another example of dangling references is when a reference type is used to be a field of a struct and the field lives short than the struct:

 fn call_color(color: String) {
        println!("My favorite color is: {}", color);
    }

    struct Target {
        name: String,
        age: i32,
        favorite_color: String, // favorite_color is a reference to a String
    }

    let outer_favorite_color = String::from("Blue");

    call_color(outer_favorite_color); // Take the color and do not return it. It consume it.

    let user1 = Target {
        name: String::from("Bob"),
        age: 42,
        favorite_color: outer_favorite_color, // Dangling reference. And complier will report an error here.

        // ERROR: use of moved value: `outer_favorite_color` value used here after moverustcClick for full compiler diagnostic
        
    };

    println!(
        "user1 has a dangling reference? fav_color is {}",
        user1.favorite_color
    );