Rust你不认识的所有权

 更新时间:2023年01月29日 10:40:59   作者:全年无休的IT老兵  
所有权对大多数开发者而言是一个新颖的概念,它是 Rust 语言为高效使用内存而设计的语法机制。所有权概念是为了让 Rust 在编译阶段更有效地分析内存资源的有用性以实现内存管理而诞生的概念

在Rust中是没有内存垃圾回收机制(GC)的,那Rust是如何保障内存安全的呢?这就引出了“所有权”这个概念。

我们看下下面这段伪代码

let s = "helloString";
t = s;
print(s);

在之前我们学习的语言中,比如C语言,对于上述伪代码的执行结果应该是正常打印"helloString" 的内容,但是在Rust中,执行上述代码时,会出现如下提示

------ 增加所有权返回内容;

而产生这个结果的原因就是触发了Rust语言中所有权机制:

  • Rust中的每一个值都有一个对应的变量作为它的所有者
  • 在同一时间内,值有且仅有一个所有者
  • 当所有者离开自己的作用域时,它持有的值就会被释放掉

在看这三条机制之前,需要先说明一下Rust中变量作用域的概念

作用域:一个对象在程序中有效的范围。

比如如下Rust代码

{
    let s = "hello";
}

在花括号内部就是变量s的作用域,当源码超出这个范围后,变量s将不再可用,即

{
    let s = "hello";
}
println!("{}", s);

打印这一句代码编译时会报错。因为在Rust语言中,当变量离开作用域时Rust会自动调用变量的"drop"函数,以此保障内存的快速回收。上述源码中,在代码执行到“}”时,Rust调用了变量s的drop函数,所以s指向的内存失效,从而导致在执行打印语句时会出错,也就是这个逻辑保障了Rust语言中内存的安全性。

我们再说回文章开头的伪代码例子,为什么编译时会出现问题,这里我们就要详细介绍一下这些语句在Rust中的逻辑。

let s = "helloString";

这句语句是声明了一个变量并使用“helloString”进行了初始化

简化展示,隐藏内部详细逻辑

t = s;

这个语句是将变量s的内容同时赋值给变量t,如下图,如果每次赋值的时候都全量内存拷贝一份的话,那整体语言性能会下降很多(毕竟变量地址大小还是不可确定的),所以处理方式是新建一个变量t,然后将内容内存指向s的指向地址。

上述情况下就出现了一个情况,同一个值被两个变量所指向,这个不符合Rust所有权的规则,所以Rust根据所有权做了一个语言限制,即当s赋值给新的变量t时,变量t指向s指向的内容,而变量s本身将被Rust擦除,所以在执行完赋值语句后,等号右侧(也就是s)将无效,在Rust语言中将这个行为叫做变量的移动,从字面意思理解也就是将变量s所有的值移动到变量t中,移动完成后s的生命周期也随之结束。

Rust有了移动这个概念,那对于其他语言中的深度拷贝或再次赋值的情况下Rust中该如何做呢?为了解决这个问题,Rust提出了另外一个变量与数据的交互方式——克隆,意思就是将s的数据完整的克隆一份给t,s的内容不变:

以Rust字符串数据结构为例子,可参考如下:

let s1 = String::from("hello");
let s2 = s1.clone();  // 此处为克隆的默认方法
println!("s1={}, s2={}", s1, s2); 

从执行结果可以看出,克隆后s1变量内容不变,还可以继续使用。

上述就是Rust所有权的一些学习心得。

到此这篇关于Rust你不认识的所有权的文章就介绍到这了,更多相关Rust所有权内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MacBook Pro安装rust编程环境的过程

    MacBook Pro安装rust编程环境的过程

    rustup是一个用于管理Rust版本和工具链的工具,这篇文章主要介绍了MacBook Pro安装rust编程环境的过程,感兴趣的朋友跟随小编一起看看吧
    2024-02-02
  • Rust 能够取代 C 语言吗

    Rust 能够取代 C 语言吗

    Rust 是 Mozilla 基金会的一个雄心勃勃的项目,号称是 C 语言和 C++ 的继任者,这篇文章主要介绍了Rust 能够取代 C 语言吗的相关知识,需要的朋友可以参考下
    2020-06-06
  • Rust错误处理之`foo(...)?`的用法与错误类型转换小结

    Rust错误处理之`foo(...)?`的用法与错误类型转换小结

    foo(...)?语法糖为Rust的错误处理提供了极大的便利,通过结合map_err方法和From trait的实现,你可以轻松地处理不同类型的错误,并保持代码的简洁性和可读性,这篇文章主要介绍了Rust错误处理:`foo(...)?`的用法与错误类型转换,需要的朋友可以参考下
    2024-05-05
  • Rust之Rhai脚本编程的示例

    Rust之Rhai脚本编程的示例

    文章介绍了如何在Rust中使用Rhai库执行脚本,包括添加依赖、创建引擎、定义脚本、执行脚本并处理结果,示例展示了如何定义一个简单的函数并调用它,输出问候信息
    2025-02-02
  • rust中智能指针的实现

    rust中智能指针的实现

    Rust智能指针通过所有权实现资源自动管理,包含Box、Rc、Arc、Mutex等类型,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • Rust中的Enum与Struct示例详解

    Rust中的Enum与Struct示例详解

    在 Rust 中,struct(结构体)和enum(枚举)是两种核心的自定义类型,分别用于组合相关数据和表示互斥的可能性,这篇文章主要介绍了Rust中的Enum与Struct示例,需要的朋友可以参考下
    2025-10-10
  • Rust常用特型之Drop特型

    Rust常用特型之Drop特型

    本文主要介绍了Rust常用特型之Drop特型,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • 如何在Rust中处理命令行参数和环境变量

    如何在Rust中处理命令行参数和环境变量

    在本章节中, 我们探讨了Rust处理命令行参数的常见的两种方式和处理环境变量的两种常见方式,感兴趣的朋友一起看看吧
    2023-12-12
  • 浅析Rust多线程中如何安全的使用变量

    浅析Rust多线程中如何安全的使用变量

    这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下
    2025-01-01
  • Rust突破编译器限制构造可修改的全局变量

    Rust突破编译器限制构造可修改的全局变量

    这篇文章主要为大家介绍了Rust突破编译器限制构造可修改的全局变量示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10

最新评论