【Rust自学】4.3. 所有权与函数

news2024/12/22 22:04:33

4.3.0 写在正文之前

在学习了Rust的通用编程概念后,就来到了整个Rust的重中之重——所有权,它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。

本章有三小节:

  • 所有权:栈内存 vs. 堆内存
  • 所有权规则、内存与分配
  • 所有权与函数(本文)

喜欢的话记得点赞、收藏加关注哦,想要跟着学下去记得关注专栏哦

4.3.1. 把值传递给函数

在语义上,把值传递给函数和把值赋给变量是类似的,所以一句话总结:函数参数传递跟赋值操作是一样的

接下来详细解释一下:把值传递给函数将会发生移动(Move)或者复制(Copy)

  • 对于实现了Copy trait的数据类型,会发生复制,所以原本的变量不受影响,能够继续使用
  • 对于没有实现Copy trait的数据类型,会发生复制,所以原本的变量会被弃用,不可使用

Copy trait、移动、复制的详细介绍在上一篇文章4.2. 所有权规则、内存与分配有讲,这里不再作阐述

fn main(){
	let machine = String::from("6657");
	wjq(machine);

	let x = 6657;
	wjq_copy(x);
	println!("x is:{}", x);
}

fn wjq(some_string::String){
	println!("{}", some_string);
}

fn wjq_copy(some_number::i32){
	println!("{}", some_number);
}
  • 对于变量machine

    • String 是一种复杂数据类型,分配在堆上,并且没有实现Copy trait。
    • machine 被传递给 wjq 函数时,发生了移动(Move),即所有权从变量 machine 转移到了函数参数 some_string
    • 此时,machine 的所有权被转移,函数 wjq 可以正常使用它,但原来的变量 machine 不再可用。如果尝试在之后使用 machine,编译器会报错。
  • 对于变量x

    • i32 是一种基本数据类型,大小固定,分配在栈上,并且实现了 Copy trait。
    • x 被传递给 wjq_copy 函数时,发生了复制(Copy),即变量 x 的值被复制了一份传递给了函数参数 some_number
    • 由于是值的复制,原变量 x 不受影响,可以在函数调用之后继续使用。
  • 对于变量some_string

    • 其作用域从第10行被声明开始,到第12行的}时就离开了作用域
    • 在离开作用域时Rust会自动调用drop函数释放变量some_string所占的内存
  • 对于变量some_number

    • 其作用域是从第14行被声明开始,到第16行的}时就离开了作用域
    • 离开作用域时不会有特殊的事情发生,因为实现了Copy trait的类型在离开作用域时不会调用 Drop

4.3.2. 返回值与作用域

函数在返回值的过程中同样也会发生所有权的转移。

fn main(){
	let s1 = give_ownership();
	let s2 = String::from("6657");
	let s3 = takes_and_gives_back(s2);
}

fn give_ownership() -> String {
	let some_string = String::from("machine");
	some_string
}

fn takes_and_gives_back(a_string:String) -> String {
	a_string
}
  • 函数 give_ownership 的行为:

    • give_ownership 函数创建了一个 String 类型的变量 some_string,它的所有权属于 give_ownership 函数。
    • some_string 作为返回值返回时,其所有权被转移到调用者,即变量 s1
    • 结果是,some_string 离开 give_ownership 的作用域后不会被释放,因为它的所有权已交给 s1
  • 函数 takes_and_gives_back 的行为:

    • takes_and_gives_back 函数接受一个 String 类型的参数 a_string。调用该函数时,传入的参数(s2)的所有权被转移到函数的参数 a_string
    • 函数将 a_string 返回时,其所有权从 a_string 再次转移给调用者,即变量 s3
    • 此时,变量 s2 不再可用,因为其所有权已被转移给 takes_and_gives_back,而函数的返回值赋给了 s3

一个变量的所有权总是遵循同样的模式:

  • 把一个值赋给其它变量时就会发生移动,只有实现了Copy trait 的类型(如基本类型i32, f64 等),在赋值时才会进行复制
  • 当一个包含堆数据的变量离开作用域时,它的值就会被drop函数清理掉,除非数据的所有权被移动到另一个变量上。

4.3.3. 让函数使用某个值而不获得其所有权

有的时候代码的本意是让函数使用变量,但不想因此失去对数据的使用权,这时候就可以这么写:

fn main(){
	let s1 = String::from("Hello");
	let (s2, len) = calculate_length(s1);
	println!("The length of '{}' is {}", s2, len);
}

fn calculate_length(s:String) -> (String, uszie) {
	let length = s.len();
	(s, length)
}

在这个例子中,s1不得不把所有权交给s,但这个函数在返回时把s也原封不动地返回,把数据所有权交给了s2,这样做就把数据所有权又交给了main函数里的变量,使得s1下的数据又能够在main函数中使用(虽然换了个变量名)。

这种做法太麻烦,也太笨了。 Rust针对这种场景有一个特性叫引用(Reference),让函数使用某个值而不获得其所有权。 这个特性将会在下篇文章中讲。

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

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

相关文章

群晖利用acme.sh自动申请证书并且自动重载证书的问题解决

前言 21年的时候写了一个在群晖(黑群晖)下利用acme.sh自动申请Let‘s Encrypt的脚本工具 群晖使用acme自动申请Let‘s Encrypt证书脚本,自动申请虽然解决了,但是自动重载一直是一个问题,本人也懒,一想到去…

level2逐笔委托查询接口

沪深逐笔委托队列查询 前置步骤 分配数据库服务器 查询模板 以下是沪深委托队列查询的请求模板&#xff1a; http://<数据库服务器>/sql?modeorder_book&code<股票代码>&offset<offset>&token<token>查询参数说明 参数名类型说明mo…

delve调试环境搭建—golang

原文地址&#xff1a;delve调试环境搭建—golang – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 由于平时不用 IDE 开发环境&#xff0c;习惯在 linux终端vim 环境下开发&#xff0c;所以找了golang的调试工具&#xff0c;delve类似gdb的调试界…

PC寄存器(Program Counter Register) jvm

在JVM&#xff08;Java虚拟机&#xff09;中&#xff0c;PC寄存器&#xff08;Program Counter Register&#xff09;扮演着至关重要的角色&#xff0c;它是JVM执行引擎的核心组成部分之一。以下是PC寄存器在JVM中的具体角色和职责&#xff1a; 指令执行指针&#xff1a; PC寄存…

线性分类器(KNN,SVM损失,交叉熵损失,softmax)

KNN 工作机制 k-近邻算法的工作机制可以分为两个主要阶段&#xff1a;训练阶段和预测阶段。 训练阶段 在训练阶段&#xff0c;k-近邻算法并不进行显式的模型训练&#xff0c;而是简单地存储训练数据集。每个样本由特征向量和对应的标签组成。此阶段的主要任务是准备好数据&…

重拾设计模式--适配器模式

文章目录 适配器模式&#xff08;Adapter Pattern&#xff09;概述适配器模式UML图适配器模式的结构目标接口&#xff08;Target&#xff09;&#xff1a;适配器&#xff08;Adapter&#xff09;&#xff1a;被适配者&#xff08;Adaptee&#xff09;&#xff1a; 作用&#xf…

StarRocks:存算一体模式部署

目录 一、StarRocks 简介 二、StarRocks 架构 2.1 存算一体 2.2 存算分离 三、前期准备 3.1前提条件 3.2 集群规划 3.3 配置环境 3.4 准备部署文件 四、手动部署 4.1 部署FE节点 4.2 部署BE节点 4.3 部署CN节点&#xff08;可选&#xff09; 4.4 FE高可用…

找数字:JAVA

题目描述 试计算在区间1 到n 的所有整数中&#xff0c;数字x&#xff08;0 ≤ x ≤ 9&#xff09;共出现了多少次&#xff1f; 例如&#xff0c;在1到11 中&#xff0c;即在1、2、3、4、5、6、7、8、9、10、11 中&#xff0c;数字1 出现了4 次。 输入描述: 输入共1行&#xf…

AI的使用:结构化提示词

根据自己的使用&#xff0c;不断的完善自己的提示词。并且像程序版本一样管理和迭代自己的提示词&#xff0c;这样才能准确的按照自己的目的去使用AI。而为了更好的管理&#xff0c;我们在一开始使用的时候&#xff0c;就要有一个易于管理的定义&#xff0c;即&#xff1a;结构…

Netcat:网络中的瑞士军刀

免责声明&#xff1a;使用本教程或工具&#xff0c;用户必须遵守所有适用的法律和法规&#xff0c;并且用户应自行承担所有风险和责任。 文章目录 一、引言二、简述三、Netcat功能&#xff1f;四、参数选项五、Netcat 的常见功能六、高级用法多连接处理创建简单的代理 七、Netc…

VS Code Copilot 与 Cursor 对比

选手简介 VS Code Copilot&#xff1a;算是“老牌”编程助手了&#xff0c;虽然Copilot在别的编辑器上也有扩展&#xff0c;不过体验最好的还是VS Code&#xff0c;毕竟都是微软家的所以功能集成更好一些&#xff1b;主要提供的是Complete和Chat能力&#xff0c;也就是代码补全…

28、基于springboot的房屋租赁系统

房屋是人类生活栖息的重要场所&#xff0c;随着城市中的流动人口的增多&#xff0c;人们对房屋租赁需求越来越高&#xff0c;为满足用户查询房屋、预约看房、房屋租赁的需求&#xff0c;特开发了本基于Spring Boot的房屋租赁系统。 本文重点阐述了房屋租赁系统的开发过程&…

【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget

目录 QLabel QFrame 例子&#xff1a; textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子&#xff1a; QTimer QProgressBar 例子&#xff1a; QCalendarWidget 例子&#xff1a; QLabel 标签控件&#xff0c;用来显示…

基于STM32的自学习智能小车设计

目录 引言系统设计 硬件设计软件设计系统功能模块 传感器模块控制模块自学习算法模块系统实现 硬件实现软件实现测试与优化结论与展望 1. 引言 随着人工智能和机器学习技术的不断发展&#xff0c;越来越多的智能小车开始实现自主学习与行为决策。传统的智能小车通常依靠固定的…

Android OpenGLES2.0开发(九):图片滤镜

“当你改变想法的时候&#xff0c;记得也要改变你的世界。”——诺曼文森特皮尔 Android OpenGLES开发&#xff1a;EGL环境搭建Android OpenGLES2.0开发&#xff08;一&#xff09;&#xff1a;艰难的开始Android OpenGLES2.0开发&#xff08;二&#xff09;&#xff1a;环境搭…

梳理你的思路(从OOP到架构设计)_简介设计模式

目录 1、 模式(Pattern) 是较大的结构​编辑 2、 结构形式愈大 通用性愈小​编辑 3、 从EIT造形 组合出设计模式 1、 模式(Pattern) 是较大的结构 组合与创新 達芬奇說&#xff1a;簡單是複雜的終極形式 (Simplicity is the ultimate form of sophistication) —Leonardo d…

vscode的keil assistant 中搜索不到全局变量

搜不到 但是在包含的文件中输入 ../../../,就是全局搜索的结果 我的文件结构是&#xff1a;\Desktop\LVGL文件系统移植&#xff08;lvgl8&#xff0e;&#xff13;&#xff09;\Projects\MDK-ARM 盲猜是keil assistant 当前文件夹打开的时候是进入到了MDK-ARM文件夹层次&…

HTML语法规范

HTML语法规则 HTML 标签是由尖括号包围的关键词&#xff0c;标签通常是成对出现的&#xff0c;例如 <html> 和 </html>&#xff0c;称为双标签 。标签对中的第一个标签是开始标签&#xff0c;第二个标签是结束标签单标签比较少&#xff0c;例如<br />&#x…

flink实现复杂kafka数据读取

接上文&#xff1a;一文说清flink从编码到部署上线 环境说明&#xff1a;MySQL&#xff1a;5.7&#xff1b;flink&#xff1a;1.14.0&#xff1b;hadoop&#xff1a;3.0.0&#xff1b;操作系统&#xff1a;CentOS 7.6&#xff1b;JDK&#xff1a;1.8.0_401。 常见的文章中&…

大模型微调---Prompt-tuning微调

目录 一、前言二、Prompt-tuning实战2.1、下载模型到本地2.2、加载模型与数据集2.3、处理数据2.4、Prompt-tuning微调2.5、训练参数配置2.6、开始训练 三、模型评估四、完整训练代码 一、前言 Prompt-tuning通过修改输入文本的提示&#xff08;Prompt&#xff09;来引导模型生…