..

Rust 学习笔记(2)

学习Rust的第二天,继续所有权以及引用。

所有权 Ownership

变量作为参数传入函数中也会发生所有权转移:

fn main() {
    let s = String::from("hello");

    takes_ownership(s);             // 此处发生所有权转移

    println!(s);                    // 编译错误,s 没有所有权
} 

fn takes_ownership(some_string: String) { // 所有权转移到 some_string 变量
    println!("{}", some_string);
} // some_string 出了作用域,对应的值释放

函数返回也会发生所有权转移:

fn main() {
    let s1 = gives_ownership();     // 所有权转移到 s1 变量 
} // s1 出了作用域,对应的值释放

fn gives_ownership() -> String {             
    let some_string = String::from("yours");

    some_string                              // 返回变量 some_string,所有权转移出函数
} // some_string 出了作用域,但没有所有权,对应的值不会释放

前面提到值的释放,背后就是对于拥有该值所有权的变量调用了drop函数:

pub fn drop<T>(_x: T) {}

拷贝和克隆 Copy & Clone

栈中的数据拷贝操作不会影响所有权,完成拷贝后各自拥有一份数据。

let x = 5; // x 的值存在栈中
let y = x; // y 拷贝了 x 的值,新 PUSH 了 5 进入栈上

println!("x = {}, y = {}", x, y); // 编译通过 ✅

堆上的数据可以通过克隆操作实现数据拷贝,变量各自拥有一份数据。

let s1 = String::from("hello"); // s1 的值存在堆中
let s2 = s1.clone();            // s2 拷贝了 s1 的值,存在另外一个堆上的地址

println!("s1 = {}, s2 = {}", s1, s2); // 编译通过 ✅

引用 Reference

引用是指变量在不转移所有权的情况下引用值:

  • 引用标识符 &
  • 解引用标识符 *
let s1 = String::from("hello");

let s = &s1;
let r = &s;

println!("{}, {}", s, r); // 编译通过 ✅

reference

函数同样也适用:

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);

    println!("The length of '{}' is {}.", s1, len); // 编译通过 ✅
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

参考资料

  • https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html