Nicksxs's Blog

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

0%

# rust学习笔记-所有权一

发表于 2021-04-18 更新于 2022-06-11 分类于 语言 ， Rust 阅读次数： 阅读次数： Disqus：

最近在看 《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 和其他的变体结构体，其大小都是不能在编译时确定，所以需要在堆上进行分配