[rust]引用与借用

41 阅读1分钟
fn main() {
    let s = String::from("hello");
    let len = calculate_length(&s);
    println!("len={}",len);
    println!("len={}",s); // 因为在函数中传递的是引用,所有此处依旧可以访问

    let s2 = &s; // & 表示引用
    let s3 = &s;
    println!("s2={}",s2);
    println!("s3={}",s3);
}

fn calculate_length(str: &String) -> usize{ // 传入一个引用,但是并不拥有它
    str.len()
} // 因为不拥有这个值,所以当引用离开其作用域后也不会被 drop

在只读的情况下,引用可以让我们避免所有权的转移,从而多次重复的读取同一个变量

fn main() {
    let mut s = String::from("hello"); // 声明一个可变变量

    {
        let s2 = &mut s; // &mut 表示借用
        println!("s2={}", s2);
    }
    {
        let s3 = &mut s;
        println!("s3={}", s3);
    }
}

变量必须声明是可变的mutable才允许被借用(因为借用允许被修改),且一个变量在同一作用域内只能被借用一次

fn main() {
    let mut s = String::from("hello");
    let s2 = &s;
    let s3 = &mut s; // 发生编译时错误:mutable borrow occurs here
    println!("s2={}",s2);
    println!("s3={}",s3);
}

可变引用mutable和不可变引用inmutable在同一作用域内不能同时出现:可变引用意味着当前值可能被修改,之后再用不可变引用时,该值可能和预想的有差别,这违背了开发者“不可变”的初衷,Rust在编译时帮助开发者做了检查

fn main() {
    let mut s = String::from("hello");
    {
        let s2 = &s; // 引用,只读
        println!("s2={}",s2);
    }
    {
        let s3 = &mut s; // 借用,可改
        s3.push_str(",world");
        println!("s3={}",s3); // hello,world
    }
    println!("s={}",s) // hello,world
}