【Rust自学】5.3. struct的方法(Method)
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
5.3.1. 什么是方法(Method)
方法和函数类似,也是用fn
关键字进行声明,方法也有名称,也有参数,也有返回值。但方法和函数也有不同之处:
- 方法在struct(或枚举或trait对象)的上下文中定义
- 方法的第一个参数总是
self
,表示方法所在的(被调用的)struct实例,类似于Python中的self
和JS中的this
。
5.3.2. 方法的实际应用
接下来还是看例子,以上一篇文章的代码为例:
struct Rectangle { width: u32, length: u32,
} fn main() { let rectangle = Rectangle{ width: 30, length: 50, }; println!("{}", area(&rectangle));
} fn area(dim:&Rectangle) -> u32 { dim.width * dim.length
}
area
这个函数的作用是计算面积,但它很特别,它只适用于矩形而不适用于其他形状或者是其他的类型。如果后面代码中要加上计算其他图形的面积的函数,那么area
这个名字就要混淆。如果改名成ractangle_area
的话又太麻烦,main
函数里所有调用了这个函数的地方都要改。
所以如果能把存储矩形长款的Rectangle
结构体和只能计算矩形面积area
这个函数结合到一起就是最好的。
对于这种需求,Rust提供了implementation
(中文意为实现),其关键字是impl
,后边跟着struct名,加上{}
,在里面像定义普通函数一样定义方法就行。
对于这个例子,struct名就是Rectangle
,把定义area
函数的代码剪贴到{}
内即可。
impl Rectangle { fn area(dim:&Rectangle) -> u32 { dim.width * dim.length }
}
但注意这里的代码还不是方法,因为方法的第一个参数必须是self
,现在的代码叫关联函数,下文会讲。
这么写是没有问题的,但还可以进一步简化。上文中说到了方法的第一个参数总是self
,所以这里也可以改一下:
impl Rectangle { fn area(&self) -> u32 { self.width * self.length }
}
你当前写的这个方法绑定在谁上,self
指的就是谁,这个代码中area
这个函数被绑定在Rectangle
上,所以self
就指的是Rectangle
,area
的参数不用拿走所有权,所以在self
前面加上&
表示印引用。
当然这么改之后,main
函数里的函数调用也会改,从函数的调用改到方法的调用——实例.方法名(参数)
:
fn main() { let rectangle = Rectangle{ width: 30, length: 50, }; println!("{}", rectangle.area());
}
rectangle.area()
的括号中不写东西是因为area
方法在定义时只使用了&self
作为参数,表示这个方法借用了self
(即rectangle
实例)的不可变引用。在调用area
时,你不需要显式地传递这个实例,因为方法调用已经隐式地知道self
是rectangle
。
整体代码如下:
struct Rectangle { width: u32, length: u32,
} impl Rectangle { fn area(&self) -> u32 { self.width * self.length }
} fn main() { let rectangle = Rectangle{ width: 30, length: 50, }; println!("{}", rectangle.area());
}
输出:
1500
5.3.3. 如何定义方法
在上面的实际应用中已经写过一遍了,所以这里就只做总结:
- 在
impl
里定义方法 - 方法的第一个参数可以是
self
、&self
或是&mut self
。可以是获得所有权、引用或可变引用,这点和其他参数一样。 - 方法可以帮助更好的组织代码,因为可以把某个类型的方法都放在
impl
块里面,避免在整个代码库里搜索struct它相关的行为了。
5.3.4. 方法调用的运算符
在C/C++中,调用方法有两种运算符
->
:其格式为object->something()
,调用指针指向的对象上的方法就使用这一种(也就是object
为指针时).
:其格式为object.something()
,调用对象上的方法就使用这种(也就是object
不为指针,是个对象时)
而object->something()
实际上是语法糖,它等同于(*object).something()
,*
表示解引用。两者的流程都是先解引用,得到对象,再在对象上调用方法。
Rust提供了自动引用/解引用的特性。也就是说,在调用方法时,Rust根据情况自动添加&
、&mut
或*
,以便object
可以匹配方法的签名。这点和Go语言一样。
举个例子,下面这两行代码效果相同:
point1.distance(&point2);
(&point1).distance(&point2);
Rust会根据情况自动在point1
前加上&
。
5.3.5. 方法的参数
方法除了self
也可以带其他参数,一个或多个都可以。
举个例子,在5.3.2的代码基础上加一个判断矩形是否能容纳下另一个长方形的功能(不考虑斜着放,也不考虑矩形的长比宽长的情况)
impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.length > other.length }
}
逻辑非常好想,只要矩形的长和宽都比另一个大就行。
然后再在main
函数里写几个Rectangle
的实例,输出比较结果看看有没有问题就行,以下是完整代码:
struct Rectangle { width: u32, length: u32,
} impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.length > other.length }
} fn main() { let rect1 = Rectangle{ width: 30, length: 50, }; let rect2 = Rectangle{ width: 10, length: 40, }; println!("{}", rect1.can_hold(&rect2));
}
输出:
true
5.3.6. 关联函数
可以在impl
块里定义不把self
作为第一个参数的函数,叫关联函数(不是方法)。它不是在实例上调用的,但它与这个类型有关联。例如: String::from()
就是String
这个类型上叫做from
的关联函数。
关联函数通常用于构造器,也就是用来被创建关联类型的一个实例。
比如说,在5.3.2的代码基础上加一个构建正方形的构造器(正方形也是特殊的矩形):
impl Rectangle { fn square(size: u32) -> Rectangle { Rectangle{ width: size, length: size, } }
}
参数只需要一个,因为构造正方形只需要一个边长。
在main
函数里调用一下这个关联函数试试,其格式为类型名::函数名(参数)
,以下是完整代码:
#[derive(Debug)]
struct Rectangle { width: u32, length: u32,
} impl Rectangle { fn square(size: u32) -> Rectangle { Rectangle{ width: size, length: size, } }
} fn main() { let square = Rectangle::square(10); println!("{:?}", square);
}
输出:
Rectangle { width: 10, length: 10 }
::
不仅可以用于关联函数,也可以用于模块创建命名空间(以后会讲)
5.3.7. 多个impl块
每个struct允许拥有多个impl
块。
比如我要把这篇文章里写过的所有的方法和关联函数都写到代码里。
可以这么写(多个impl
块):
#[derive(Debug)]
struct Rectangle { width: u32, length: u32,
} impl Rectangle { fn area(&self) -> u32 { self.width * self.length }
} impl Rectangle { fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.length > other.length }
} impl Rectangle { fn square(size: u32) -> Rectangle { Rectangle{ width: size, length: size, } }
} fn main() { let square = Rectangle::square(10); println!("{:?}", square);
}
也可以这么写(合在一个impl
块里):
#[derive(Debug)]
struct Rectangle { width: u32, length: u32,
} impl Rectangle { fn area(&self) -> u32 { self.width * self.length } fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.length > other.length } fn square(size: u32) -> Rectangle { Rectangle{ width: size, length: size, } }
} fn main() { let square = Rectangle::square(10); println!("{:?}", square);
}
相关文章:
【Rust自学】5.3. struct的方法(Method)
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 5.3.1. 什么是方法(Method) 方法和函数类似,也是用fn关键字进行声明,方法也有名称,也有参数ÿ…...
单片机 STM32入门
一、什么是单片机 单片机(Microcontroller Unit,MCU)是一种集成电路芯片,它将计算机的CPU、存储器(包括RAM和ROM)、输入/输出接口等集成在一个芯片上。单片机通常用于嵌入式系统,能够执行特定的…...
OneCode:开启高效编程新时代——企业定制出码手册
一、概述 OneCode 的 DSM(领域特定建模)出码模块是一个强大的工具,它支持多种建模方式,并具有强大的模型转换与集成能力,能够提升开发效率和代码质量,同时方便团队协作与知识传承,还具备方便的仿…...
学python还是学java?哪个相对来说比较容易上手?
在比较Python和Java哪个更容易上手时,可以从多个维度进行分析,包括语法简洁性、学习资源、应用领域、学习曲线等。 一、语法简洁性 Python:Python的语法简洁明了,更接近自然语言,易于理解和记忆。它使用缩进来表示代…...
C语言项目 天天酷跑(上篇)
前言 这里讲述这个天天酷跑是怎么实现的,我会在天天酷跑的下篇添加源代码,这里会讲述天天酷跑这个项目是如何实现的每一个思路,都是作者自己学习于别人的代码而创作的项目和思路,这个代码和网上有些许不一样,因为掺杂了…...
Windows 11 安装 Dify 完整指南 非docker环境
# Windows 11 安装 Dify 完整指南## 前置要求- Python 3.11 - Node.js 18 - PostgreSQL 14 - Redis for Windows - Git - Ollama (可选,用于本地模型)## 详细安装步骤### 1. 安装必要软件1. **Python 3.11**- 从 https://www.python.org/downloads/release/python-…...
MySQL变量
文章目录 MySQL变量系统变量查看系统变量设置系统变量 自定义变量用户变量局部变量 MySQL变量 MySQL变量分为系统变量和自定义变量 系统变量 系统变量有全局变量和会话变量 查看系统变量 #查看全局系统变量 show global variables; #根据条件查询全局系统变量 show global …...
Ubuntu离线安装Docker容器
前言 使用安装的工具snap安装在沙箱中,并且该沙箱之外的权限有限。docker无法从其隔离的沙箱环境访问外部文件系统。 目录 前言准备环境卸载已安装的Docker环境快照安装的Dockerapt删除Docker 安装docker-compose下载执行文件将文件移到 /usr/local/bin赋予执行权限…...
ensp 关于acl的运用和讲解
ACL(Access Control List,访问控制列表)是一种常用于网络设备(如路由器、交换机)上的安全机制,用于控制数据包的流动与访问权限。ACL 可以指定哪些数据包允许进入或离开某个网络接口,基于不同的…...
Linux(Centos 7.6)yum源配置
yum是rpm包的管理工具,可以自动安装、升级、删除软件包的功能,可以自动解决软件包之间的依赖关系,使得用户更方便软件包的管理。要使用yum必须要进行配置,个人将其分为三类,本地yum源、局域网yum源、第三方yum源&#…...
[WASAPI]音频API:从Qt MultipleMedia走到WASAPI,相似与不同
[WASAPI] 从Qt MultipleMedia 来看WASAPI 最近在学习有关Windows上的音频驱动相关的知识,在正式开始说WASAPI之前,我想先说一说Qt的Multiple Media,为什么呢?因为Qt的MultipleMedia实际上是WASAPI的一层封装,它在是线…...
什么是MVCC?
MVCC(多版本并发控制,Multi-Version Concurrency Control)是一种用于数据库管理系统中的并发控制的技术。它允许多个事务同时对同一数据进行读取和修改,而不会相互干扰,从而提高了数据库的并发性能。以下是对MVCC的详细…...
C/C++基础错题归纳
文章目录 第1天1.下面程序段的运行结果是:答案知识补充 2.当一个类A 中没有声明任何成员变量与成员函数,这时sizeof(A)的值是多少?答案知识补充 3.下面程序输出是什么?答案其他讲解 第1天 1.下面程序段的运行结果是: char C[5]{‘a’,’b’…...
Nginx 常用安全头
Web 应用中配置 HTTP 安全响应头是提升网站安全性的重要一步。合理配置 Nginx 的安全头,可以抵御常见的安全威胁(如 XSS、点击劫持、MIME 类型嗅探等),增强用户隐私保护和传输安全性。 常见的 HTTP 安全头及其作用 1. Content-Se…...
消息队列(一)消息队列的工作流程
什么是消息队列 首先,代入一个场景,我现在做一个多系统的集成,分别有系统A、B、C、D四个系统,A系统因为使用产生了业务数据,B、C、D需要使用这些数据做相关的业务处理和运算,最基本的做法就是通过接口通信…...
LeetCode 2605 从两个数字数组里生成最小数字
探寻两个数组数位关联下的最小数字问题 题目描述 给定两个只包含 1 到 9 之间数字的数组 nums1 和 nums2,并且每个数组中的元素都是互不相同的。我们需要返回最小的数字,要求这个数字满足两个数组都至少包含这个数字的某个数位。例如,若 nu…...
AI新书推荐:深度学习和大模型原理与实践(清华社)
本书简介 在这个信息爆炸、技术革新日新月异的时代,深度学习作为人工智能领域的重要分支,正引领着新一轮的技术革命。《深度学习和大模型原理与实践》一书,旨在为读者提供深度学习及其大模型技术的全面知识和实践应用的指南。 本书特色在于…...
32单片机串口数据接收、空闲IDLE中断详解
一、前提说明 一开始写单片机程序的时候不太清楚空闲中断这个东西,每次用串口接收数据,都要再开一个定时器,在定时器内进行倒计时,每次接收数据就重置计时时间,计时结束就触发中断,再判断所有接收的数据&am…...
WebRtc webrtc-streamer部署
文章目录 本文档只是为了留档方便以后工作运维,或者给同事分享文档内容比较简陋命令也不是特别全,不适合小白观看,如有不懂可以私信,上班期间都是在得 WebRtc webrtc-streamer 部署 docker run -p 8000:8000 -it mpromonet/webrt…...
shiro注入filter内存马(绕过长度限制)
shiro环境 https://github.com/yyhuni/shiroMemshell(实验环境) 这里用的 Client_memshell.java package com.example.demo;import javassist.ClassPool; import javassist.CtClass; import org.apache.shiro.crypto.AesCipherService; import org.ap…...
Springboot + vue3 实现大文件上传方案:秒传、断点续传、分片上传、前端异步上传
参考:https://juejin.cn/post/6870837414852886542#heading-9 一般计算大文件的md5都是前端来做,因为如果后端来做,那得等到上传成功后才能计算md5值,并且读取的时间也很长。 为了解决文件大传输慢的问题,前端可以通…...
渗透Vulnhub-DC-9靶机
本篇文章旨在为网络安全渗透测试行业靶机教学。通过阅读本文,读者将能够对渗透Vulnhub系列DC-6靶机有定的了解 一、信息收集阶段 DC-9靶场信息: DC-9靶场介绍: https://www.vulnhub.com/entry/dc-9,412/ DC-9靶场下载: https://download.vu…...
springboot477基于vue技术的农业设备租赁系统(论文+源码)_kaic
摘 要 使用旧方法对农业设备租赁系统的信息进行系统化管理已经不再让人们信赖了,把现在的网络信息技术运用在农业设备租赁系统的管理上面可以解决许多信息管理上面的难题,比如处理数据时间很长,数据存在错误不能及时纠正等问题。这次开发的农…...
CentOS常见命令
CentOS(Community ENTerprise Operating System)基于Red Hat Enterprise Linux(RHEL)源代码开发,是常用的Linux发行版之一。在CentOS系统中,有许多命令用于管理和操作系统,以下是一些CentOS系统…...
oracle 设置归档日志存放路径
oracle 设置归档日志存放路径 1、创建新目录 mkdir /archive chown -R oracle:oinstall /archive 注:条件允许的话,/archive 目录应独立挂载。1、便于监控目录使用率;2、避免和其它文件混淆,便于管理。 2、设置归档日志存放路…...
机器学习1-简单神经网络
相比传统的机器学习算法,深度学习做出了哪些改进呢?其实两者在理论结构上是一致的,即:模型假设、评价函数和优化算法,其根本差别在于假设的复杂度 构建简单神经网络(未训练): # 封装…...
C++的侵入式链表
非侵入式链表 非侵入式链表是一种链表数据结构,其中每个元素(节点)并不需要自己包含指向前后节点的指针。链表的结构和节点的存储是分开的,链表容器会单独管理这些指针。 常见的非侵入式链表节点可以由以下所示,即&a…...
MFC案例:图片文件转图标(ico)格式
本案例程序目的是将一般图像文件转换成图标格式(ico)。实现起来不是很复杂,这里为了介绍MFC的具体使用方法,在程序界面上分成几个功能块,包括:打开图像文件、选择ICON大小、转换、预览、保存等。相关具体步骤如下: 一、…...
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
文章目录 一、软件下载安装1、Unity官网2、下载Unity Hub 二、修改Unity Hub配置1、设置Unity Hub中文语言2、修改默认存储目录 三、安装unity编辑器1、点击安装编辑器2、版本选择3、关于版本号4、安装模块选择5、等待下载完成自动安装即可6、追加unity和模块 四、许可证管理专…...
东子生物完成A轮战略融资,数字商品交易全新升级为数商时代
2024年11月23日,东子生物数字时代正式上线,标志着公司全面迈入“数商时代”,作为国内领先的生物科技企业,东子生物在数字化浪潮中精准布局,以创新科技推动产业升级,以全新的思维引领健康产业,兼…...
数据结构经典算法总复习(上卷)
第一章:数据结构导论 无重要考点,仅需了解时间复杂度。 第二章:线性表 1.获得线性表第i个元素 void GetElem_sq(SqList L, int i, ElemType &e) {if (i<1 || i>L.length) ErrorMsg("Invalid i value"); //注意错误监…...
电脑使用CDR时弹出错误“计算机丢失mfc140u.dll”是什么原因?“计算机丢失mfc140u.dll”要怎么解决?
电脑使用CDR时弹出“计算机丢失mfc140u.dll”错误:原因与解决方案 在日常电脑使用中,我们时常会遇到各种系统报错和文件丢失问题。特别是当我们使用某些特定软件,如CorelDRAW(简称CDR)时,可能会遇到“计算…...
oracle使用imp命令导入dmp文件
需求: 增量导入 tbl_servicelegalclause 表数据(dmp格式)。 导入思路:使用 dba 创建一个 临时库,先将 tbl_servicelegalclause.dmp(增量的数据) 文件导入到 临时库,然后确认临时库数…...
电脑出现 0x0000007f 蓝屏问题怎么办,参考以下方法尝试解决
电脑蓝屏是让许多用户头疼的问题,其中出现 “0x0000007f” 错误代码更是较为常见且棘手。了解其背后成因并掌握修复方法,能帮我们快速恢复电脑正常运行。 一、可能的硬件原因 内存问题 内存条长时间使用可能出现物理损坏,如金手指氧化、芯片…...
Logback日志框架中的继承机制详解
在Logback框架中,logger的继承机制是基于层级结构(hierarchical context)工作的。每个logger都被分配一个名称,这个名称可以看作是一个路径或目录结构,从而形成了一个逻辑上的树状结构。这种结构使得日志记录具有很强的…...
[Unity]【图形渲染】【游戏开发】Shader数学基础4-更多矢量运算
在计算机图形学和着色器编程中,矢量运算是核心的数学工具之一。矢量用于描述空间中的位置、方向、速度等各种物理量,并在图形变换、光照计算、纹理映射等方面起着至关重要的作用。本篇文章将详细讲解矢量和标量之间的乘法与除法、矢量的加法与减法、矢量的模与单位矢量、点积…...
node.js的异步工作之---回调函数与回调地狱
回调函数:在 Node.js 中,很多 API 都是异步的,通常通过回调函数来处理操作完成后的结果。这种回调模式虽然非常高效,但会导致代码逐渐变得难以维护,尤其是当有多个异步操作嵌套时(即回调地狱)。…...
tcp 的三次握手与四次挥手
问1: 请你说一下tcp的三次握手一次握手两次握手三次握手问: 为什么不四(更多)次握手? 问 2: 请说一下 tcp 的 4 次挥手一次挥手两次挥手问题:能不能等到数据传输完成再返回 ack? 三次挥手四次挥手问: 为什么要等两个最大报文存在时间? bg: tcp 是可靠的连接,如何保证 建立连…...
《三角洲行动》游戏运行时提示“缺失kernel32.dll”:问题解析与解决方案
《三角洲行动》游戏运行时提示“缺失kernel32.dll”:问题解析与解决方案 作为软件开发领域的一名从业者,我深知电脑游戏运行过程中可能遇到的各种挑战,尤其是文件丢失、文件损坏以及系统报错等问题。今天,我将以经典游戏《三角洲…...
Android——自定义按钮button
项目中经常高频使用按钮,要求:可设置颜色,有圆角且有按下效果的Button 一、自定义按钮button button的代码为 package com.fslihua.clickeffectimport android.annotation.SuppressLint import android.content.Context import android.gra…...
Pandas基础学习(1)
之前看的pandas的教材和课程里,内容参差不齐,实际使用很少的方法的内容有点多,导致很乱而且记不住那么多,这个帖子尽量用最少的文字,最精炼的语言来总结比较实用的方法,内容主要来源于《利用python进行数据…...
20241224在Ubuntu20.04.6下给X99平台上的M6000显卡安装驱动程序
20241224在Ubuntu20.04.6下给X99平台上的M6000显卡安装驱动程序 2024/12/24 16:18 下载驱动程序: https://www.nvidia.cn/drivers/lookup/ https://www.nvidia.cn/drivers/results/ https://www.nvidia.cn/drivers/details/237923/ https://www.nvidia.cn/drivers/l…...
批量多线程给TXT文档插入相关腾讯AI【高质量无水印无版权】原创图片
给蜘蛛访问的网站文章插入相关图片,可以带来以下好处: 1、提升用户体验:图片能够直观地展示文章内容,帮助用户更好地理解和消化信息。对于阅读者来说,图文并茂的内容往往更具吸引力,也能提高他们的阅读…...
保护模式基本概念
CPU 架构 RISC(Reduced Instruction Set Computer) 中文即"精简指令集计算机”。RISC构架的指令格式和长度通常是固定的(如ARM是32位的指令)、且指令和寻址方式少而简单、大多数指令在一个周期内就可以执行完毕 CISC&…...
mysql 查询优化之字段建立全文索引
最近在接手一些老项目时发现表设计存在问题导致查询较慢 例如一张旧表的设计: 模糊匹配某个关键字时,需要十几秒左右,而且表的数据量不多 都知道mysql8.0版本InnoDB引擎都支持全文索引了,因此可以在content建立全文索引,但全文索引对中文支持并不完善…...
redis和mysql的区别
Redis是一种非关系型数据库(NoSQL),将数据存储在缓存中,这虽然提高了运行效率,但是保存时间却很短。将数据存储在内存中,因此读写速度非常快,特别适合用于需要高速访问的场景,如缓存…...
【Laravel】接口的访问频率限制器
Laravel 接口的访问频率,你可以在 Laravel 中使用速率限制器(Rate Limiter)。以下是一个详细的步骤,展示如何为这个特定的 API 路由设置速率限制: 1. 配置 RouteServiceProvider 首先,确保在 App\Provide…...
LabVIEW水泵性能测试系统
在现代工业应用中,水泵作为一种广泛使用的流体输送设备,其性能的可靠性对整个生产系统的稳定运行至关重要。通过LabVIEW软件配合专业硬件设备,设计了一套水泵性能测试系统,实现对各类水泵的综合性能测试与分析,提升水泵…...
基于推理的目标检测 DetGPT
基于推理的目标检测 DetGPT flyfish detgpt.github.io 近年来,由于大型语言模型(LLMs)的发展,计算机视觉领域取得了重大进展。这些模型使人类与机器之间能够进行更有效、更复杂的交互,为模糊人类与机器智能界限的新技…...
【Java 基础】-- ArrayList 和 Linkedlist
目录 1. Java 中的 ArrayList 和 LinkedList 简介 ArrayList LinkedList 2. 相同数量级下的内存开销对比 ArrayList 的内存开销 LinkedList 的内存开销 3. 它们的速度对比 总结 1. Java 中的 ArrayList 和 LinkedList 简介 ArrayList 数据结构:基于动态数组…...