当前位置: 首页 > news >正文

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

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),让函数使用某个值而不获得其所有权。 这个特性将会在下篇文章中讲。

相关文章:

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

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

【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)

一、什么是分布式锁 我们在上篇文章中实现了单机模式下的秒杀业务。其中采用了synchronized加锁来解决各种线程安全问题。而synchronized关键字是依赖于单机的JVM,在集群模式下,每个服务器都有独立的JVM,如果此时还采用synchronized关键字加…...

用docker快速安装电子白板Excalidraw绘制流程图

注:本文操作以debian12.8 最小化安装环境为host系统。 一、彻底卸载原有的残留 apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 二、设置docker的安装源 # Add Dockers official G…...

使用Turtle库实现,鼠标左键绘制路径,用鼠标右键结束绘制,小海龟并沿路径移动

使用Turtle库实现,鼠标左键绘制路径,用鼠标右键结束绘制,小海龟并沿路径移动 Turtle库是Python标准库的一部分,它提供了一种基于命令的图形绘制方式。Turtle模块通过一个“海龟”(Turtle)对象在屏幕上移动…...

人工智能入门是先看西瓜书还是先看花书?

在人工智能入门时,关于先看《机器学习》(西瓜书)还是先看《深度学习》(花书)的问题,实际上取决于个人的学习目标和背景。 《机器学习》(西瓜书)由周志华教授撰写,是一本…...

winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭

winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭 protected override void WndProc(ref Message m){#region 处理点击窗体标题栏放大缩小问题,禁用点击窗体标题栏放大缩小//logger.Info($&…...

进程内存转储工具|内存镜像提取-取证工具

1.内存转储,内存转储(Memory Dump)是将计算机的物理内存(RAM)内容复制到一个文件中的过程,这个文件通常被称为“内存转储文件”或“核心转储文件”(Core Dump),内存转储的主要目的是…...

数据结构day5:单向循环链表 代码作业

一、loopLink.h #ifndef __LOOPLINK_H__ #define __LOOPLINK_H__#include <stdio.h> #include <stdlib.h>typedef int DataType;typedef struct node {union{int len;DataType data;};struct node* next; }loopLink, *loopLinkPtr;//创建 loopLinkPtr create();//…...

(OCPP服务器)SteVe编译搭建全过程

注意&#xff1a;建议使用3.6.0&#xff0c;我升级到3.7.1&#xff0c;并没有多什么新功能&#xff0c;反而电表的实时数据只能看到累计电能了&#xff0c;我回退了就正常&#xff0c;数据库是兼容的&#xff0c;java版本换位java11&#xff0c;其他不变就好 背景&#xff1a;…...

Mybatis分页插件的使用问题记录

项目中配置的分页插件依赖为 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.7</version></dependency>之前的项目代码编写分页的方式为&#xff0c;通过传入的条件…...

36. Three.js案例-创建带光照和阴影的球体与平面

36. Three.js案例-创建带光照和阴影的球体与平面 实现效果 知识点 Three.js基础 WebGLRenderer WebGLRenderer 是Three.js中最常用的渲染器&#xff0c;用于将场景渲染到网页上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobject可选参数&#…...

CentOS 7 安装、测试和部署FastDFS

目录 FastDFS环境搭建 安装 libfastcommon 库 安装FastDFS 查看编译后的文件 FastDFS配置 FastDFS启动 启动tracker服务 启动storage服务 查看storage是否已经注册到了tracker下 查看存储文件的目录 FastDFS重启 FastDFS关闭 使用fdfs_test进行测试 修改client.co…...

全志H618 Android12修改doucmentsui选中图片资源详情信息

背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 进入file文件管理器后,点击选中图片资源,选中功能按钮,获取信息,不显示“调试信息(仅开发者)”;现状是,获取信息,显示“调试信…...

【083】基于51单片机智能烘手器【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统LCD1602液晶显示DS18B20温度传感器TCRT5000红外感应传感器AT24C02存储芯片风扇加热片继电器LED灯按键设置。 1、设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片&#xff1b; 2、系统采用DS18B20温度传感器感应当前环…...

uniApp使用腾讯地图提示未添加maps模块

uniApp使用腾讯地图&#xff0c;打包提示未添加maps模块解决方案 这是报错信息&#xff0c;在标准基座运行的时候是没问题的&#xff0c;但是打包后会提示未添加&#xff0c;可以通过在mainfest里面把地图插件上腾讯地图的key更换高德地图的key&#xff0c;定位服务可以继续用腾…...

未来趋势系列 篇五:自主可控科技题材解析和股票梳理

文章目录 系列文章自主可控科技题材分析国产算力信创(信息技术应用创新)华为鸿蒙军工信息化半导体芯片卫星互联网工业软件股票梳理系列文章 未来趋势系列 篇一:AI题材解析和股票梳理 未来趋势系列 篇一(加更):AI医疗题材解析和股票梳理 未来趋势系列 篇二:HBM题材解析和…...

Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题

文章目录 前言功能简述1. 自定义日志文件名2. 归档规则 && 压缩2.1. 归档配置2.2. 归档压缩2.3. 日志格式 && 编码 现象原因解决办法 前言 在 Springboot 应用中&#xff0c;默认使用 logback-spring.xml 配置日志相关 功能简述 1. 自定义日志文件名 <fi…...

maven-resources-production:ratel-fast: java.lang.IndexOutOfBoundsException

Maven生产环境中遇到java.lang.IndexOutOfBoundsException的问题&#xff0c;尝试了重启电脑、重启IDEA等常规方法无效&#xff0c;最终通过直接重建工程解决了问题。 Rebuild Project 再启动OK...

K8s docker-compose的入门

一、Docker Compose 简介 什么是 Docker Compose&#xff1f; 用于定义和运行多容器 Docker 应用的工具。Docker Compose 的主要功能 使用 docker-compose.yml 文件定义服务。一键启动和管理多容器环境。安装与环境准备 安装 Docker 和 Docker Compose。检查版本&#xff1a;d…...

去雾Cycle-GAN损失函数

文章目录 GAN-LossIdentity-LossDP-lossCycle-Loss G和F都是生成器 G是hazy → \to → gt F是gt → \to → hazy D y D_y Dy​判别无雾图是真实还是生成的&#xff1f; D x D_x Dx​判别有雾图是真实还是生成的&#xff1f; GAN-Loss 在 DAM-CCGAN 中存在两个判别器 D x D_x D…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...