首页 >> 行业

环球快讯:1.6所有权解决了什么问题?及其使用方法

2023-02-10 07:59:48来源:ByteBunny

上一节我们快速浏览了函数及控制结构,加上1.4节的数据类型,是不是跃跃欲试,想大干一场了呢?哈哈,脚印还得一个一个踩,我们今天还得说一说rust的一个重要概念--所有权。


(资料图)

我们先不讲所有权概念,先来看一个例子,有什么问题,再看看主流语言都是怎么解决这些问题的,有什么痛点,再来看rust的解决方法,就水到渠成,能更好地理解了。

考虑一个查找函数:(力扣高手勿喷~)给一个数组和一个目标值,用循环遍历数组找出等于目标值的元素索引。

在C++中,findpos是传了一个数组的引用,所以堆上数组还是只有一份,只是引用计数+1了(浅拷贝),而多个调用就会出现多个引用,这些引用是通过专门维护引用的代码来管理的,运行时会带来一定的性能损耗。

在java中,GC是通过追踪式定时查看哪些内存标记不使用了,就会清理掉,同样也会带来运行时性能损耗。

我们可以看出,主流语言都会有一些问题。那rust有什么好方法吗?

有,rust借鉴了C++的move语义,配合使用所有权,高效、优美地解决了以上问题,下面我们来看rust是怎么做到的:

我加了注释,你们应该很容易能看明白,rust通过move移动语义把数组所有权交给了函数参数,在函数里data拥有数组的所有权,而函数结束时数组也被安全释放。

这里没有使用多个引用,也不用在运行时再去管理引用计数或者定时清理标记未使用内存块,而是在编译期就安全的管理了堆内存。这就是rust优秀的内存管理之一,优雅、高效。只要能编译通过,rust程序一般而言都不会有什么问题,所以我们很多时候都是在和编译器作斗真~

来看看rust所有权三大原则:

一个值只能被一个变量拥有,这个变量是这个值的所有者。一个值在同一时刻只能有一个所有者,所以在函数传参、变量赋值、函数返回等行为,都是旧所有者把所有权移动给新所有者,以符合这一规则。当所有者离开其作用域,他拥有的值被丢弃,内存安全释放。

所有权虽然很好的解决了多重引用、引用计数管理以及运行时定时检查内存的问题,但是也规定了一个时刻只能有一个变量拥有值,那像上个例子,若我们程序功能要求在函数传参后,需要继续使用原data,还想要使用它指向的数组呢?

这就要用到clone()函数,她可以把数组在内存拷贝一份,然后传回新数组地址给函数调用(深拷贝):

当然,如果有需求需要多次clone(),这样深拷贝多个堆数据也不高效,还会用到下一节要说到的copy和borrow等语法。

好了,我们学习了rust很重要的所有权概念,知道了他解决了什么问题,为什么要这么设计,还对比了rust和主流语言的内存管理机制,相信你已经更好理解了所有权,我觉得写rust程序越写越能养成好习惯,因为编译器会不停地督促我写出更健壮的代码~~对于今天的内容你有什么看法呢?欢迎在评论区留言讨论!如果觉得文章有用,记得点赞关注加收藏,以后就会第一时间收到文章推送啦:D

本文由ByteBunny原创,欢迎关注,带你一起长知识!

关键词: 使用方法 什么问题

相关新闻