Rust 所有权和生命周期总结

Rust About 2,437 words

引用和借用

abc变量&abc引用test函数借用&abc作为参数。

struct Abc {
    id: u32,
    name: String
}

let abc = Abc {
    id: 10,
    name: String::from("abc"),
};

println!("abc address={:p}", &abc);

test(&abc);

fn test(s: &Abc) {
    // ...
}

引用的规则

在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。

引用必须总是有效的。(离开作用域后不可用)

所有权

传入引用获取所有权,借用不获取所有权。

生命周期

引用没有生命周期,只有借用有生命周期。

代码示例

fn main() {
    struct Abc {
        id: u32,
        name: String,
        info: String,
    }

    fn just_print_struct(a: Abc) -> Abc {
        println!("in fn a={:p}, a.id={:p}, a.name={:p}, a.info={:p}", &a, &a.id, &a.name, &a.info);
        a
    }

    let abc = Abc {
        id: 100,
        name: String::from("abc"),
        info: String::from("info"),
    };

    println!("before fn abc={:p}, abc.name={:p}, abc.info={:p}", &abc, &abc.name.as_ptr(), &abc.info);

    let return_abc = just_print_struct(abc);

    println!("after fn return_abc={:p}, return_abc.name={:p}, return_abc.info={:p}", &return_abc, &return_abc.name, &return_abc.info);

    // println!("after fn abc={:p}, abc.name={:p}, abc.info={:p}", &abc, &abc.name.as_ptr(), &abc.info);

}

输出:发现结构体的地址值都不同。

before fn abc=0x16ba62bf0, abc.name=0x16ba62cd0, abc.info=0x16ba62c08
in fn a=0x16ba62d18, a.id=0x16ba62d48, a.name=0x16ba62d18, a.info=0x16ba62d30
after fn return_abc=0x16ba62ce0, return_abc.name=0x16ba62ce0, return_abc.info=0x16ba62cf8

如果不注释掉最后一行,编译器会报错,因为abc引用再传递给just_print_struct函数时,所有权已经给了该函数,无法在后续代码中使用。

error[E0382]: borrow of moved value: `abc`
  --> src/main.rs:25:91
   |
13 |     let abc = Abc {
   |         --- move occurs because `abc` has type `Abc`, which does not implement the `Copy` trait
...
21 |     let return_abc = just_print_struct(abc);
   |                                        --- value moved here
...
25 |     println!("after fn abc={:p}, abc.name={:p}, abc.info={:p}", &abc, &abc.name.as_ptr(), &abc.info);
   |                                                                                           ^^^^^^^^^ value borrowed here after move
   |
note: consider changing this parameter type in function `just_print_struct` to borrow instead if owning the value isn't necessary
  --> src/main.rs:8:29
   |
8  |     fn just_print_struct(a: Abc) -> Abc {
   |        -----------------    ^^^ this parameter takes ownership of the value
   |        |
   |        in this function
Views: 515 · Posted: 2023-05-03

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh