Rust 引用和借用

发布时间: 更新时间: 总字数:786 阅读时间:2m 作者: IP属地: 分享 复制网址

本文详细介绍Rust引用(reference)和借用(borrowing)特性。

引用 & 借用

引用(reference)是 Rust 的特性:

  • & 符号表示引用,允许程序引用某些值而不取得其所有权,类似于其他语言的指针,示例:&String
    • 应用的变量在回收时,不会释放内存
    • 应用的变量不能修改,否则报错:cannot borrow *x as mutable, as it is behind a & reference
  • * 符号表示解引用
fn main() {
    let str = String::from("hello str");
    let len = len_fn(&str);  // 引用 str,不发生 move,后面可以继续使用
    println!("str = {}, len = {}", str, len)
}

fn len_fn(s: &String) -> usize {
    s.len()
}
  • 借用:将引用作为函数参数的行为叫借用

    • 不可以修改 借用 的标量
  • 可变引用

fn main() {
    let mut str = String::from("hello str");
    let len = len_fn(&mut str);  // 引用 str,不发生 move,后面可以继续使用
    println!("str = {}, len = {}", str, len)
}

fn len_fn(s: &mut String) -> usize {
    s.push_str(", somethine...");
    s.len()
}
  • 可变引用的限制:在特定的作用域内,对某一块数据,只能有一个可变的引用,用于防止数据竞争(编译报错)
    • 数据竞争会在以下三种情况下发生:
      • 两个或多个指针同时访问同一个数据
      • 至少有一个指针用于写入数据
      • 没有使用任何机制来同步对数据的访问
    • 不可以同时拥有一个可变引用和一个不可变引用,如:let mut s = String::from("hello string"); let s1 = &s; let s2 = &s; let s3 = &mut s; 报错:cannot borrow s as mutable because it is also borrowed as immutable
    • 可以同时有多个不可变引用
  • 可以通过创建新的作用域,来允许非同时的创建多个可变引用
fn main() {
    let mut str = String::from("hello str");
    {
        let s1: &mut String = &mut str;
    }

    let s2 = &mut str;
}

引用的规则

  • 在任何时刻,只能满足以下条件之一:
    • 一个可变的引用
    • 任意数量不可变的引用
  • 引用必须一直有效

悬空引用(Dangling References)

悬空引用(Dangling References):一个指针引用了内存中的某个地址,而该块内存可能已经释放并分配给其他人使用。

在 Rust 里,编译器可以保证应用永远都不是悬空引用:如果引用了某些数据,编译器保证在引用离开作用域之前数据不会离开作用域。

示例:

fn main() {
    let str = generate_str();
    println!("{}", str)
}

fn generate_str() -> &String {
    let s = String::from("hello string...");
    &s
}

编译报错:

error[E0106]: missing lifetime specifier
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数