美文网首页
【RUST_BASIC】Rust 所有权

【RUST_BASIC】Rust 所有权

作者: ixiaolong | 来源:发表于2021-11-15 11:59 被阅读0次

1 所有权规则

  • Rust 中的每一个值都有一个被称为其所有者(owner)的变量
  • 值在任一时刻有且只有一个所有者
  • 当所有者(变量)离开作用域,这个值将被丢弃

2 内存与分配

栈(stack)中的所有数据都必须占用已知且固定的大小,在编译时大小未知或大小可能变化的数据,要改为存储在堆(heap)上。

入栈比在堆上分配内存要快,因为(入栈时)分配器无需为存储新数据去搜索内存空间;其位置总是在栈顶。相比之下,在堆上分配内存则需要更多的工作,这是因为分配器必须首先找到一块足够存放数据的内存空间,并接着做一些记录为下一次分配做准备。

对于保存在堆上数据类型:

  • 必须在运行时向内存分配器(memory allocator)请求内存
  • 需要一个当我们处理完数据时将内存返回给分配器的方法

Rust 可通过各自类型的方法进行内存的分配,例如 String 类型调用 String::from 即可进行内存的分配;其内存回收的策略是,内存在拥有它的变量离开作用域后就被自动释放:

{
    let s = String::from("hello"); // 从此处起,s 是有效的

    // 使用 s
}                                  // 此作用域已结束,
                                   // s 不再有效

当变量离开作用域,Rust 在结尾的 } 调用一个drop函数释放 String 的内存。

3 数据交互

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

let s2 = s1 之后,Rust 认为 s1 不再有效,因此 Rust 不需要在 s1 离开作用域后清理任何东西,否则将会造成二次释放(double free)的错误。

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

此后 s1 仍可继续使用。

3.3 拷贝
let x = 5;
let y = x;

在这里没有执行克隆操作,但 x 仍有效可继续使用,原因是像整型这样的在编译时已知大小的类型被整个存储在栈上,所以拷贝其实际的值是快速的。这意味着没有理由在创建变量 y 后使 x 无效。

Rust 有一个叫做 Copy trait 的特殊注解,可以用在类似整型这样的存储在栈上的类型上,如果一个类型实现了 Copy trait,那么一个旧的变量在将其赋值给其他变量后仍然可用。另外,Rust 不允许自身或其任何部分实现了 Drop trait 的类型使用 Copy trait。

任何一组简单标量值的组合都可以实现 Copy trait,任何不需要分配内存或某种形式资源的类型也都可以实现 Copy trait,如下是一些 Copy 的类型:

  • 所有整数类型,比如 u32。
  • 布尔类型,bool,它的值是 true 和 false。
  • 所有浮点数类型,比如 f64。
  • 字符类型,char。
  • 元组,当且仅当其包含的类型也都实现 Copy trait 的时候。比如,(i32, i32) 实现了 Copy,但 (i32, String) 就没有。

4 引用

引用符号为 &,允许使用值但不获取其所有权。

let s1 = String::from("hello");
let len = calculate_length(&s1);

&s1 语法创建了一个指向 s1 的引用,但是并不拥有它,所以当引用停止使用时,它所指向的值也不会被丢弃。创建一个引用的行为称为借用(borrowing)。

引用默认不允许修改引用的值,添加 mut 的可变引用可修改引用的值:

fn main() {
    let mut s = String::from("hello");
    change(&mut s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}

另外,要避免悬垂引用(Dangling References)的出现,此时编译会报错:

fn main() {
    let reference_to_nothing = dangle();
}

fn dangle() -> &String {
    let s = String::from("hello");

    &s
}

引用的规则如下:

  • 在任意给定时间,要么只能有一个可变引用,要么只能有多个不可变引用
  • 引用必须总是有效的

5 slice

slice 是一个没有所有权的数据类型 ,其允许引用集合中一段连续的元素序列,而不用引用整个集合。

// 字符串slice
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];

// 数组slice
let a = [1, 2, 3, 4, 5];
let slice = &a[1..3];

相关文章

  • 【RUST_BASIC】Rust 所有权

    1 所有权规则 Rust 中的每一个值都有一个被称为其所有者(owner)的变量 值在任一时刻有且只有一个所有者 ...

  • Rust 所有权

    认识所有权 所有权是 rust独特的功能,它让 rust无需垃圾回收即可保证内存安全。 什么是所有权 Rust核心...

  • 【RUST_BASIC】Rust 并发

    1 线程 调用 thread::spawn 函数创建线程并传递一个闭包,包含新线程运行的代码: 使用 join 等...

  • 【RUST_BASIC】Rust 宏

    参考 https://kaisery.github.io/trpl-zh-cn/ch19-06-macros.ht...

  • The Rust programming language 读书

    所有权概念是 Rust 语言的核心功能 Rust 没有垃圾回收(GC)机制 Rust 通过所有权和相关工具保障内存...

  • 【RUST_BASIC】Rust 高级 trait

    1 关联类型 关联类型(associated types)是一个将类型占位符与 trait 相关联的方式,这样 t...

  • Rust 所有权

    引用[https://www.runoob.com/rust/rust-ownership.html] 所有权规则...

  • 2019-08-27

    Rust思考 所有权,Rust通过所有权机制移除了垃圾回收器,但是所有权机制绝非坦途,它对开发人员提出了更高的要求...

  • 【RUST_BASIC】Rust 智能指针

    1 Box 最简单直接的智能指针是 box,其类型是 Box,其允许将一个值放在堆上,留在栈上的则是指...

  • 【RUST_BASIC】Rust 基本概念

    1 变量与常量 使用 let 关键字声明变量,变量名后面为变量类型: Rust 是静态类型(statically ...

网友评论

      本文标题:【RUST_BASIC】Rust 所有权

      本文链接:https://www.haomeiwen.com/subject/ymqxtrtx.html