rust笔记2 OwnerShip基础概念

首先,要搞清楚栈内存和堆内存对应了那些类型。rust的整型、浮点型、bool型、字面字符串型和tuple型都是栈内存上的;如果使用=,那么这些数据会拷贝一份新的内容。

然后,要了解rust的变量作用域,这点直接参考C++的即可。

最后给出Owership的规则:

  • rust的每个值都有对应的变量名,这个变量名是owner
  • 每个值同时只能有一个owner
  • 当owner离开作用范围时,值会被释放掉。

String在rust中是堆内存的内容,堆内存中的内容如果使用=,那么默认是使用移动语义的,移动语义直接参考C++的std::move即可。给出代码实例说明:

fn main() {
    let str = "hello";

    let s1 = String::from(str);
    println!("s1 = {}", s1);
    let s2 = s1;
    println!("s2 = {}", s2);
    // println!("s1 = {}", s1);  // 直接调用是错误的,此时s1堆内存的owner已经是s2了
}

实际在内存中发生的情景
rust笔记2 OwnerShip基础概念_第1张图片
和C++的移动语义一样,内存中实际的控制权被转换到了s2中了,s1此时已经是空的了。

如果我们想要s1任然有效,那么可以通过克隆的方式,比如:

let s1 = String::from("hello");
let s2 = s1.clone();

在函数使用的时候,尤其要注意这个问题,给出代码实例:

fn main() {
    let str = String::from("hello world !");
    takes_ownership(str);
    // println!("str = {}", str);  // 直接调用会报错,因为已经被移动了
    let str1 = String::from("hello world !");
    takes_ownership(str1.clone());  // 可以安全调用,因为使用了clone了
    println!("str1 = {}", str1);
}

fn takes_ownership(some_string: String) {  // 一旦调用,外界的String所有权会被移动到这里
    println!("takes_ownership(): {}", some_string);
}

上述代码中,takes_ownership函数在调用后,原来的String内容会被销毁,如果不想销毁,可以使用一个trick:

fn main() {
    let str = String::from("hello world !");
    let str1  = takes_ownership(str);
    println!("str1 = {}", str1);
}

fn takes_ownership(some_string: String) -> String {  // 一旦调用,外界的String所有权会被移动到这里
    println!("takes_ownership(): {}", some_string);
    some_string
}

函数内部使用expression的方式返回即可

你可能感兴趣的:(rust笔记,rust,Ownership)