Rust 所有权

314 阅读2分钟

所有权

  • 没有垃圾回收机制
  • 内存管理机制

在搞明白所有权之前,有一些基础的知识作为前缀条件。这些前缀条件就是 rust 有别与其他语言的通识部分。这些部分造成了 Rust 有所有权的部分。

所有权规则

  • 值具有一个所有者,所有者具有所有权。
  • 一个所有者只能有一个所有权。
  • 失效性,不在程序运行范围失效。

栈中变量

  • 基本数据类型。

示例:

let a = 1;
let b = a; // b = 1, a = 1

这一点与 JavaScript 表现是一致的。

基本数据类型:

  • 整形数据
  • 布尔类型
  • 浮点型
  • 字符类型
  • 包含基本类型的元组

引用类型

堆中一般保存引用类型数据, 那么我们如何创建引用类型数据?

let a = String::from("hello");
let b = a
  • a 变量引用的是一个变量,这个变量保存是一个字符串对象,字符串对象保存在堆内存中。
  • 但是有一点特殊的是: a 的赋值预期和 JavaScript 是不一致的。a 赋值给 b 之后,a 自己就空了,只有 b 指向了原来的内存。不向 JavaScript 指针指向同一个对象。
  • 此时访问 a,会报错。那么我们始终会遇到 a 也指向堆中字符串对象的时候,rust 是如何解决这个问题: a 其实一个对象,字符串对象,那么它上面默认挂载了 clone 方法, clone 方法能够解决上面的问题。
  • 使用克隆是一种方式,我们想一想其实我们可以间接访问。间接访问的操作符号 &, 它没有克隆行为,赋值其实就是创建引用关系。引用不会获取所有权,引用只能通过租借获取所有权。
  • 租借,引用的本质是租借值的所有权
  • 引用变量,不能被修该

所有权

所有权就是变量的访问权利,rust 中特殊设计,所有权会程序的运行和操作。访问权限发生变化

fn main() {
    let s1 = String::from("hello");
    let s2 = &s1;
    let s3 = s1;
    println!("{}", s2);
}

s2 是租借的 s1, 但是后面我们将 s1 移动到了 s3 上面。s2 访问 s1 时就没有用了。

函数中的所有权

  • 函数参数,参数是变量,传入参数视为参数变量移动,基本数据不符合这个规则。
  • 函数返回值,被当作函数返回值的变量所有权将会被移动出函数并返回到调用函数的地方,而不会直接被无效释放。
  • 所有的释放,符合我们认知的作用域规则。

参考