Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

0%

rust学习笔记-所有权一

最近在看 《rust 权威指南》,还是难度比较大的,它里面的一些概念跟之前的用过的都有比较大的差别
比起有 gc 的虚拟机语言,跟像 C 和 C++这种主动释放内存的,rust 有他的独特点,主要是有三条

  • Rust中的每一个值都有一个对应的变量作为它的所有者。
  • 在同一时间内,值有且只有一个所有者。
  • 当所有者离开自己的作用域时,它持有的值就会被释放掉。

    这里有两个重点:
  • s 在进入作用域后才变得有效
  • 它会保持自己的有效性直到自己离开作用域为止

然后看个案例

let x = 5;
let y = x;

这个其实有两种,一般可以认为比较多实现的会使用 copy on write 之类的,先让两个都指向同一个快 5 的存储,在发生变更后开始正式拷贝,但是涉及到内存处理的便利性,对于这类简单类型,可以直接拷贝
但是对于非基础类型

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

println!("{}, world!", s1);

有可能认为有两种内存分布可能
先看下 string 的内存结构

第一种可能是

第二种是

我们来尝试编译下

发现有这个错误,其实在 rust 中let y = x这个行为的实质是移动,在赋值给 y 之后 x 就无效了

这样子就不会造成脱离作用域时,对同一块内存区域的二次释放,如果需要复制,可以使用 clone 方法

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

println!("s1 = {}, s2 = {}", s1, s2);

这里其实会有点疑惑,为什么前面的x, y 的行为跟 s1, s2 的不一样,其实主要是基本类型和 string 这类的不定大小的类型的内存分配方式不同,x, y这类整型可以直接确定大小,可以直接在栈上分配,而像 string 和其他的变体结构体,其大小都是不能在编译时确定,所以需要在堆上进行分配

请我喝杯咖啡