RUST所有权相关问题

news/2024/10/3 15:04:52

先介绍一下RUST的所有权规则:
1.Rust 中的每一个值都有一个所有者(owner)。
2.值在任一时刻有且只有一个所有者。
3.当所有者(变量)离开作用域,这个值将被丢弃。

变量与数据交互的方式包括两种:移动和克隆。
移动就是转交值的所有权,如let x=y(x的类型未实现Copy trait),x失去了值的所有权而y获取了值的所有权。
克隆就是新建一份和原值相同的副本。克隆也包括两种:Copy和Clone。Copy需要实现Copy trait,就是对值做简单的按位复制操作,且Copy仅对栈内存做按位复制;而Clone需要实现Clone trait,需要为它所拥有的所有值重新分配资源,栈和堆都可以是Clone的目标。

先说Copy。并不是所有类型都可以实现 Copy trait。只有满足以下条件的类型才能实现 Copy:
1.类型本身是 POD(Plain Old Data)类型,即不包含任何指针或引用。
2.类型的所有字段都实现了Copy。
3.该类型必须实现了Clone。

常见的默认实现了Copy trait的类型有:
1.基本数据类型
2.所有元素类型都实现了Copy trait的元组
3.元素类型是实现了Copy trait的数组

对于常规的赋值、传参和方法返回值,如果该类型实现了Copy trait,那默认使用Copy;否则移动。
赋值:
struct mystruct { //mystruct未实现Copy trait value: i32, } fn main() { let m1= mystruct { value:25 }; let m2 = m1; println!("m2.value = {}", m2.value); println!("m1.value = {}", m1.value); //会报错,因为m1值的所有权被移动了 }
编译报错:

struct mystruct { //mystruct实现了Copy trait value: i32, } impl Clone for mystruct { fn clone(&self) -> mystruct { *self } } impl Copy for mystruct {} fn main() { let m1= mystruct { value:25 }; let m2 = m1; println!("m2.value = {}", m2.value); println!("m1.value = {}", m1.value); }
编译通过:

传参:
struct mystruct { //mystruct未实现Copy trait value: i32, } fn testParamStruct(m: mystruct){ println!("value = {}", m.value); } fn main() { let m1= mystruct { value:25 }; testParamStruct(m1); println!("value = {}", m1.value); //会报错,因为m1值的所有权被移动了 }
编译报错:

struct mystruct { //mystruct实现了Copy trait value: i32, } fn testParamStruct(m: mystruct){ println!("value = {}", m.value); } impl Clone for mystruct { fn clone(&self) -> mystruct { *self } } impl Copy for mystruct {} //实现Copy trait fn main() { let m1= mystruct { value:25 }; testParamStruct(m1); println!("value = {}", m1.value); //会报错,因为m1值的所有权被移动了 }
编译通过:

再说说Clone。也不是所有类型可以实现Clone triat。要实现Clonen trait,类型内部的其他类型必须都实现了Clone trait。要进行Clone,需要显式调用clone。
常见的默认实现了Clone trait的类型有:
1.基本数据类型
2.String和&str
3.所有元素类型都实现了Clone trait的元组
4.元素类型是实现了Clone trait的数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/67369.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

GoogLeNet训练CIFAR10[Pytorch+训练信息+.pth文件]

0 引言GoogLeNet,它是一种深度卷积神经网络,由Google研究人员在2014年提出,用于图像识别任务。 CIFAR-10是一个常用的图像识别数据集,包含10个类别,每个类别有6000张32x32的彩色图像。 本文使用Pycharm及Pytorch框架搭建GoogLeNet神经网络框架,使用CIFAR10数据集训练模型…

IntelliJ IDEA中,代码折叠(Code Folding)功能 取消 默认的 方法体自动展开

默认情况下 方法体 代码折叠后,再次启动 IDEA 时 会自动展开 取消 下面的多选框 则 下次启动不会自动展开

2024国庆S综合强化Day3

今天的题比较简单。 A link

“订单、账单、支付单”关系解析

当交易、支付等体系糅合在一起时,可能会产生许多单据或单号,这个时候,要怎么理解单据在交易正、逆向中的联系?这篇文章里,作者结合设定场景做了解读,或许可以帮你理解“订单、账单、支付单”关系。有朋友提出一个问题比较典型,可能是很多朋友的疑问点:整个交易、支付、…

闲话 10.2

闲话 10.2 你说得对但我还是想写些废话出来你说的对,以前假期比上不足比下有余,现在没有下了。10.1 上午的唐氏模拟赛,忙活一上午只有 55pts,还因为 T4 freopen 开错了挂 15pts。 T1 感觉哪里很对但很怪,死活调不出来大样例三,于是两个小时就摆了,结果大败而归,事实上…

C++ 容器适配器

除了顺序容器外,标准库还定义了三个顺序容器适配器:stack、queue和priority_queue。适配器(adaptor)是标准库中的一个通用概念****。容器、迭代器和函数都有适配器。本质上,一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。一个容器适配器接受一种已有的…

【HITCON-Training】Lab 14 - MagicHeap

学习于2024-10-03 12:50:42 星期四 心得感想: 分析 ida一打开就看到很明显的提示(毕竟是教学关卡):那么我们需要将magic修改为一个大于0x1305的数,并且该程序没有开PIE,那么magic地址就是固定的。 Delete操作删的非常彻底,很明显这里没有任何可以利用的:Create部分看起…