Rust-所有权(ownership)

这篇具有很好参考价值的文章主要介绍了Rust-所有权(ownership)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

Rust入门学习系列-Rust 的核心功能(之一)是 所有权(ownership)。引入这个概念是为了更好的管理计算机的内存。下面篇幅让我们来研究下这个功能有什么神奇之处。


一、管理计算机内存的方式

常见的编程语言中计算机内存管理方式:

  • Java:Java使用Java虚拟机(JVM)来管理计算机内存。JVM有一个垃圾回收器(GC),用于自动回收不再使用的对象并释放内存。
  • .NET:.NET使用托管堆来管理内存。在.NET中,对象分配在托管堆上,当对象不再使用时,垃圾回收器会自动回收内存。
  • Go:Go使用垃圾回收器(GC)来管理内存。Go的GC使用标记-清除算法来识别和清除不再使用的对象,并回收相关的内存。
  • JavaScript:JavaScript使用自动垃圾回收器来管理内存。JavaScript引擎会周期性地检查对象是否不再被引用,如果对象没有引用,则会将其标记为垃圾并回收相关的内存。
  • Rust:Rust使用所有权系统来管理内存。在Rust中,每个值都有一个所有者,并且只有当前所有者可以访问和修改该值。当值的所有者超出作用域时,该值将被自动释放。

通过上面的几种常用语言的列举分析,所有运行的程序都必须管理其使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时不断地寻找不再使用的内存;在另一些语言中,开发者必须亲自分配和释放内存。Rust 则选择了第三种方式:通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查。在运行时,所有权系统的任何功能都不会减慢程序。

所有权规则

那么所有权管理有什么规则?所有权的规则:

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

二、Rust中的 move

在Rust中,move操作指的是将变量的所有权从一个变量转移到另一个变量。当对某个值进行move操作时,该值将不再有效,不能再被访问或使用。

move操作通常发生在以下几种情况下:

  1. 将一个变量赋值给另一个变量时,会发生move操作。例如:
let a = String::from("Hello");
let b = a; // move操作,a的所有权转移到b
// println!("{}", a); // 这里会出现编译错误,a已经不再有效
  1. 函数参数传递时,会发生move操作。例如:
fn take_ownership(s: String) {
    // ...
}

let s = String::from("Hello");
take_ownership(s); // move操作,s的所有权转移到函数take_ownership中
// println!("{}", s); // 这里会出现编译错误,s已经不再有效
  1. 函数返回值时,会发生move操作。例如:
fn create_string() -> String {
    let s = String::from("Hello");
    s // move操作,将s作为返回值
}

let s = create_string(); // move操作,create_string函数的返回值所有权转移到s
// println!("{}", s); // 这里会出现编译错误,s已经不再有效

需要注意的是,通过clone()方法可以创建值的深拷贝,而不是move操作。例如:

let a = String::from("Hello");
let b = a.clone(); // 深拷贝,a的所有权不会转移
println!("{}", a); // 正常打印 Hello
println!("{}", b); // 正常打印 Hello

除了移动操作,我们还可以借用值的引用来使用它,而不会转移所有权。借用可以是不可变的(引用为&T)或可变的(引用为&mut T)。以下是一个示例:

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1); // 通过引用借用s1值的所有权,计算长度
    println!("The length of '{}' is {}.", s1, len);

    // s1.push_str(", world!"); // 这一行代码将导致编译错误,因为我们只借用了s1的不可变引用

    let mut s2 = String::from("hello");
    change(&mut s2); // 通过可变引用借用s2的值的所有权,进行修改
    println!("s2 = {}", s2);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

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

在这个例子中,我们将s1的引用传递给calculate_length函数,它只借用了s1的值的不可变引用来计算其长度,而没有转移所有权。我们还可以将s2的可变引用传递给change函数,它通过可变引用修改了s2的值。

Rust通过引用和所有权规则实现了借用和移动操作。通过移动操作,我们可以转移值的所有权到新的变量中。通过借用操作,我们可以共享值的引用,而不转移所有权。这种机制在Rust中确保了内存安全和线程安全。

Copy trait

下面的代码可以运行~

fn main() {
    let x = 5;
    let y = x;

    println!("x = {}, y = {}", x, y);
}

Rust 有一个叫做 Copy trait 的特殊标注,可以用在类似整型这样的存储在栈上的类型上。如果一个类型实现了 Copy trait,那么一个旧的变量在将其赋值给其他变量后仍然可用。

那么哪些类型实现了 Copy trait 呢?你可以查看给定类型的文档来确认,不过作为一个通用的规则,任何一组简单标量值的组合都可以实现 Copy,任何不需要分配内存或某种形式资源的类型都可以实现 Copy 。如下是一些 Copy 的类型:

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

三、Rust中的 clone

Rust中的clone是一种方法,用于创建一个数据的完全副本。它会创建一个与原始数据相同的新数据,但是新数据独立于原始数据,具有自己的所有权。

在Rust中,数据的所有权规则决定了每个值在任何给定时间点只能有一个所有者。当我们将一个值赋给另一个变量时,所有权会转移给新变量。当我们通过引用来传递值时,所有权不会转移,只是借用该值。

使用clone方法可以在不转移所有权的情况下创建数据的完整副本。这对于需要在多个地方使用同一份数据时非常有用,而不想转移所有权。

以下是一个简单的示例,演示了clone方法的使用:

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

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

在这个例子中,我们创建一个字符串s1,然后通过调用clone方法创建了一个s2的副本。两个变量现在都拥有自己的所有权,并且可以独立于彼此使用。

需要注意的是,clone方法是一个昂贵的操作,因为它会对数据进行深拷贝。在处理大型数据结构时,应该谨慎使用clone,以避免性能问题。

clone方法是Rust中用于创建完整副本的方法,而不转移数据所有权。它对于需要在不同地方使用相同数据副本的场景非常有用。


总结

Rust 是一种系统级编程语言,其最重要的特性是所有权系统。这个特性可以使程序员避免许多常见的内存安全问题。

在 Rust 中,每个值都有一个所有者。这个所有者负责分配和释放值的内存。当所有者离开作用域时,它会自动释放相应的内存。

Rust 的所有权系统通过三个规则来实现:

  1. 唯一性规则:每个值都只能有一个所有者。当值被分配给另一个所有者时,原来的所有者将失效。这可以有效防止两个所有者同时释放同一个内存。

  2. 移动语义:当将值赋给另一个变量时,它将从原来的变量中移动到新的变量中。这意味着原来的变量将失效,并且不能再使用它。这确保了所有权的唯一性规则。

  3. 借用规则:可以通过借用来暂时地使用一个值,而不改变所有权。借用是通过引用来实现的,借用的变量称为引用。引用只是对值的一个视图,它不具备所有权。借用规则规定了如何正确地使用和管理引用。

总结来说,Rust 的所有权系统通过唯一性规则、移动语义和借用规则保证了内存的安全性和有效性。这使得 Rust 可以在不使用垃圾回收机制的情况下,实现高性能和安全的系统级编程。

参考: Rust 中文文档文章来源地址https://www.toymoban.com/news/detail-827236.html

到了这里,关于Rust-所有权(ownership)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Rust所有权

    什么是所有权 所有程序在运行时都必须管理其使用计算机内存的方式: 一些语言中具有垃圾回收机制,在程序运行时有规律地寻找不再使用的内存,比如C#和Java。 在另一些语言中,程序员必须自行分配和释放内存,比如C/C++。 而Rust则是通过所有权系统管理内存: 所有权是

    2024年02月07日
    浏览(40)
  • Rust之所有权

    程序需要管理自己在运行时使用的计算机内部空间。Rust语言采用包含特定规则的所有权系统来管理内存,这套规则允许编译器在编译的过程中执行检查工作,而不会产生任何的运行时开销。 Rust中的每一个值都有一个对应的变量作为它的所有者; 在同一时间内,值有且仅有一

    2024年02月16日
    浏览(46)
  • 【Rust】Rust学习 第四章认识所有权

    所有权(系统)是 Rust 最为与众不同的特性,它让 Rust 无需垃圾回收(garbage collector)即可保障内存安全。因此,理解 Rust 中所有权如何工作是十分重要的。 4.1 所有权 所有运行的程序都必须管理其使用计算机内存的方式。一些语言中具有垃圾回收机制,在程序运行时不断地

    2024年02月13日
    浏览(53)
  • Rust核心功能之一(所有权)

    目录 1、什么是所有权? 1.1 所有权规则  1.2 变量作用域 1.3 String 类型 1.4 内存与分配 变量与数据交互的方式(一):移动 变量与数据交互的方式(二):克隆 只在栈上的数据:拷贝 1.5 所有权与函数 1.6 返回值与作用域 所有权(系统)是 Rust 最为与众不同的特性,对语言的

    2024年02月04日
    浏览(42)
  • Rust-所有权和移动语义

    拿C语言的代码来打个比方。我们可能会在堆上创建一个对象,然后使用一个指针来管理这个对象: 接下来,我们可能需要使用这个对象: 然而,这段代码之后,谁能猜得到,指针p指向的对象究竟发生了什么?它是否被修改过了?它还存在吗,是否已经被释放?是否有另外一个指

    2024年01月18日
    浏览(38)
  • rust学习——栈、堆、所有权

    栈和堆是编程语言最核心的数据结构,但是在很多语言中,你并不需要深入了解栈与堆。 但对于 Rust 这样的系统编程语言,值是位于栈上还是堆上非常重要, 因为这会影响程序的行为和性能。 栈和堆的核心目标就是为程序在运行时提供可供使用的内存空间。 栈 栈按照顺序存

    2024年02月07日
    浏览(72)
  • 30天拿下Rust之所有权

    概述         在编程语言的世界中,Rust凭借其独特的所有权机制脱颖而出,为开发者提供了一种新颖而强大的工具来防止内存错误。这一特性不仅确保了代码的安全性,还极大地提升了程序的性能。在Rust中,所有权是一种编译时检查机制,用于追踪哪些内存或资源何时可

    2024年03月08日
    浏览(39)
  • Rust语法:所有权&引用&生命周期

    垃圾回收管理内存 Python,Java这类语言在管理内存时引用了一种叫做垃圾回收的技术,这种技术会为每个变量设置一个引用计数器(reference counter),来统计每个对象的引用次数。 一旦某个对象的引用数为0,垃圾回收器就会择取一个时机将其所占用的空间回收。 以Python为例子

    2024年02月12日
    浏览(54)
  • 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念

    【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 本章节将讲解 Rust 独有的概念(所有权)。所有权是 Rust 最独特的特性,它使得 Rust 能够

    2024年02月10日
    浏览(44)
  • Rust 基础入门 —— 2.3.所有权和借用

    Rust 的最主要光芒: 内存安全 。 实现方式: 所有权系统 。 因为我们这里实际讲述的内容是关于 内存安全的,所以我们最好先复习一下内存的知识。 然后我们,需要理解的就只有所有权概念,以及为了开发便利,进一步引出的引用借用概念。 内存作为存储程序运行时数据

    2024年02月12日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包