迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

Rust 中的 move 语义

作者:迹忆客 最近更新:2023/03/21 浏览次数:

在本文中,我们将了解 Rust 中的移动语义。

在 Rust 中移动语义

在 Rust 中,所有类型都是可变的,所有移动操作都相当于原始数据在新位置的位副本。Move 通过引用或可变引用将任何捕获的变量转换为按值捕获的变量。

当涉及线程时,通常使用移动。

Rust 过程也具有破坏性。例如,离开变量后,该变量在代码中不再可用。

在 Rust 中,移动始终通过复制对象本身的数据而不破坏原始对象来实现。它永远不会通过复制对象的托管资源或执行自定义代码来实现。

Rust 对不需要移动语义的类型例外。相反,该值包含表示它的所有必要信息,并且没有堆分配或资源由该值管理,例如 i32

这些类型实现了特殊的 Copy 特征,因为复制成本低,并且是传递给函数或管理分配的默认方法:

fn foo(bar: i32) {
    // Implementation
}

let var: i32 = 9;
foo(var); // copy
foo(var); // copy
foo(var); // copy

默认函数调用对 Copy 以外的类型(例如 String)使用移动语义。在 Rust 中,当一个变量被移动时,它的生命周期会提前结束。

在编译时,move 替换了块末尾的析构函数调用,因此为 String 编写如下代码是错误的:

fn foo(bar: String) {
    // Implementation
}

let var: String = "Hello".to_string();
foo(var); // Move
foo(var); // Compile-Time Error
foo(var); // Compile-Time Error

克隆 rust 需要实现,但对于所有移动都是相同的:复制值中的内存并且不调用原始值的析构函数。

而在 Rust 中,通过这种精确的实现,所有类型都是可移动的;不可移动类型不存在(尽管不可移动值存在)。字节必须在新位置编码有关该值管理的资源的信息,例如指针,就像它们在先前位置中所做的一样有效。

Rust 有一种称为 pinning 的机制,它在类型系统中指示特定值永远不会再次移动,它可用于实现自引用值并在异步中使用。

例子:

fn destroy_box(z: Box<i32>) {
    println!("The box that contains {} is destroyed", z);
}

fn main() {
    let a = 5u32;
    let b = a;
    println!("a is {}, and y is {}", a, b);

    let m = Box::new(5i32);

    println!("a contains: {}", m);
    let n = m;
    destroy_box(n);
}

destroy_box 函数获取上述源代码中堆分配内存的所有权。首先,z 被销毁,内存被释放。

m 是指向堆分配整数的指针。

输出:

a is 5, and y is 5
a contains: 5
The box that contains 5 is destroyed

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

用 Rust 读写文件

发布时间:2023/03/21 浏览次数:152 分类:编程语言

本教程演示了在不同版本的 Rust 中读取和写入文件的方式。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便