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

rust方法和关联函数

Rust方法

在大多数面向对象的语言中都存在方法,方法一般和类关联在一起。在Rust中也是类似的,方法和对象总是一起出现。Rust的方法和结构体,枚举,特征一起使用。

定义方法

Rust使用关键字impl来定义方法,例如:

#![allow(unused)]
fn main() {
// 这个圆的结构体定义可以看做是由x,y来定位圆的圆心,radius是圆的半径。
struct Circle {x: f64,y: f64,radius: f64,
}impl Circle {// 这种方法往往用于初始化当前结构体的实例fn new(x: f64, y: f64, radius: f64) -> Circle {Circle {x,y,radius,}}// Circle的方法,&self表示借用当前的Circle结构体fn area(&self) -> f64 {std::f64::consts::PI * (self.radius * self.radius)}
}
}

因此,在rust中定义方法的格式如下:

impl 结构体名|枚举名|特征名{函数1函数2...
}

另外一点需要注意的是,&self实际上是self:&Self的简写,在一个impl块内,Self指代被实现方法的结构体(枚举或者特征)类型,self指代此类型的实例。因此在上面这个例子中,&Self实际指代Circle这个结构体类型,而self则是该结构体的一个实例化对象。实际上和其它面向对象语言是差不多的。(self和C++的this指针实际上是类似的,只不过this是C++方法的隐含参数,而rust的self和python的self在表现形式上几乎是一模一样的。)方法的第一个参数必须有一个名为 self 的Self 类型的参数,所以 Rust 让你在第一个参数位置上只用 self 这个名字来缩写。

还有一点需要注意,那就是new是Circle的关联函数,因为它的第一个参数不是self,且new并不是关键字;而area是Circle的方法,它的第一个参数是&self。

需要注意的是,self 依然有所有权的概念:

  • self 表示 Circle 的所有权转移到该方法中,这种形式用的较少
  • &self 表示该方法对 Circle 的不可变借用
  • &mut self 表示可变借用

方法名和结构体字段名相同

在 Rust 中,允许方法名跟结构体的字段名相同,一般来说,方法跟字段同名,往往适用于实现get访问器,例如:

pub struct Rectangle {width: u32,height: u32,
}impl Rectangle {pub fn new(width: u32, height: u32) -> Self {       // Self指代的类型是RectangleRectangle { width, height }}pub fn width(&self) -> u32 {return self.width;}
}fn main() {let rect1 = Rectangle::new(30, 50);println!("{}", rect1.width());
}

用这种方式,我们可以把 Rectangle 的字段设置为私有属性,只需把它的 new 和 width 方法设置为公开可见,那么用户就可以创建一个矩形,同时通过访问器 rect1.width() 方法来获取矩形的宽度,因为 width 字段是私有的,当用户访问 rect1.width 字段时,就会报错。

上面这段代码同时展示了关联函数new在使用的时候是结构体名::函数名,而方法则是obj.method。接着在main函数中加上下面两行代码。

let rect2 = &Rectangle::new(3, 3);
println!("{}", rect2.width());

可以看到,对于一个引用,我们依旧是采用点(.)运算符来调用width方法的,没有C/C++中的区分,指针使用->,对象使用点(.)。这背后是Rust拥有自动引用和解引用的功能。方法调用是 Rust 中少数几个拥有这种行为的地方。他是这样工作的:当使用 object.something() 调用方法时,Rust 会自动为 object 添加 &、&mut 或 * 以便使 object 与方法签名匹配。也就是说,这些代码是等价的:

#![allow(unused)]
fn main() {
#[derive(Debug,Copy,Clone)]
struct Point {x: f64,y: f64,
}impl Point {fn distance(&self, other: &Point) -> f64 {let x_squared = f64::powi(other.x - self.x, 2);let y_squared = f64::powi(other.y - self.y, 2);f64::sqrt(x_squared + y_squared)}
}
let p1 = Point { x: 0.0, y: 0.0 };
let p2 = Point { x: 5.0, y: 6.5 };// 下面这两行等价,因为Rust会帮我们做自动引用和解引用。
p1.distance(&p2);
(&p1).distance(&p2);
}

多个impl定义

每个结构体都允许拥有多个 impl 块。例如:

struct Rectangle {width: u32,height: u32,
}impl Rectangle {fn area(&self) -> u32 {self.width * self.height}
}impl Rectangle {fn can_hold(&self, other: &Rectangle) -> bool {self.width > other.width && self.height > other.height}
}

此处没有什么实际意义,只是为了说明rust允许这样的语法,在泛型和trait的时候,这一点会变得有用很多。

关联函数

定义在 impl 中且没有 self 的函数被称之为关联函数,它没有self,不能用obj.method的形式调用,而是使用::的形式来调用,因此他是函数不是方法,而他又在impl中,与结构体紧密关联,因此称为“关联函数”。关联函数在功能上比C++的静态成员函数要灵活的多。

Rust 中有一个约定俗成的规则,使用 new 来作为构造器的名称,出于设计上的考虑,Rust 特地没有用 new 作为关键字

参考资料

  1. Rust语言圣经
  2. Rust程序设计语言

相关文章:

rust方法和关联函数

Rust方法 在大多数面向对象的语言中都存在方法,方法一般和类关联在一起。在Rust中也是类似的,方法和对象总是一起出现。Rust的方法和结构体,枚举,特征一起使用。 定义方法 Rust使用关键字impl来定义方法,例如&#…...

深度学习如何训练出好的模型

深度学习在近年来得到了广泛的应用,从图像识别、语音识别到自然语言处理等领域都有了卓越的表现。但是,要训练出一个高效准确的深度学习模型并不容易。不仅需要有高质量的数据、合适的模型和足够的计算资源,还需要根据任务和数据的特点进行合…...

智慧教室系统--重点设备监控系统

随着教育信息化的不断发展,智慧教室已成为现代教育的重要组成部分。而智慧教室的设备管理和维护也变得越来越重要。一旦智慧教室的重要设备出现故障或异常,将会对教学活动产生不利影响,因此建立智慧教室重点设备监控系统是必要的。一、智慧教…...

Linux中断处理

目录 一、什么是中断 二、中断处理原理 三、中断接口 3.1 中断申请 3.2 中断释放 3.3 中断处理函数原型 四、按键驱动 一、什么是中断 一种硬件上的通知机制,用来通知CPU发生了某种需要立即处理的事件 分为: 1. 内部中断 CPU执行程序的过程中&am…...

python中安装gurobi和pycharm没有语法提示问题解决

安装gurobi第一步 :下载gurobi ( http://www.gurobi.com ) ,需要注册账号第二步、申请License注册如果可以通过校园网, 则直接生成。不能的话,通过网站,发邮件申请 http://www.gurobi.cn/NewsView1.Asp?id4第三、邮件…...

滤波算法:经典卡尔曼滤波

卡尔曼滤波实质上就是基于观测值以及估计值二者的数据对真实值进行估计的过程。预测步骤如图1所示: ​图1 卡尔曼滤波原理流程图 假设我们能够得到被测物体的位置和速度的测量值 ​,在已知上一时刻的最优估计值 ​以及它的协方差矩阵 的条件下&#xff…...

flask框架(下)

文章目录flask框架(下)werkzeug简介请求上下文flask 处理方案回到 wsgi_app 方法中push 源码总结补充flask框架(下) werkzeug简介 Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也…...

Airbyte架构

作为一款技术复杂的数据集成管道,Airbyte的架构模式非常清晰明了。Airbyte应用模式Airbyte管道架构UI:一个易于使用的图形界面,用于与Airbyte API进行交互。WebApp Server:处理 UI 和 API 之间的连接。Config Store:存…...

anchor box只是先验知识,bounding box是一种过程,ground truth才是标准答案,

anchor boxes是一组提前预定义的边框,这些框的宽高和数据集中目标物体的宽高大体是一致的,换句话说,数据集中的绝大多数物体都能找到与其大小一致的anchor box。 举例来说,如果数据集中包含苹果、猫,那么这组anchor bo…...

带你轻松实现通讯录(C语言版)

文章目录前言通讯录初始化通讯录运行的基本框架和菜单增添联系人删除联系人查找联系人修改联系人信息展示通讯录通讯录联系人个数排序通讯录文件操作储存通讯录信息销毁通讯录整体代码Contacts.hContacts.ctest.c写在最后前言 学习C语言的小伙伴,相信都要经历实现通…...

渗透测试之交换式网络嗅探实验

渗透测试之交换式网络嗅探实验实验目的一、实验原理1.1 网络嗅探器Sniffer的工作原理1.2 网络嗅探器的分类1.3 网络嗅探器Sniffer的作用二、实验环境2.1 操作机器2.2 实验工具Sniffer2.3 安装工具Sniffer三、实验步骤1. 熟悉Sniffer工具的启动2. 进行监听3. 熟悉Sniffer工具的介…...

rust 安装

rust 安装一、需要一个c的环境二、配置环境变量三、开始安装一、需要一个c的环境 安装Visual Studio 二、配置环境变量 Rust需要安装两个东西,一个是rustup,一个是cargo。所以你需要设置两个环境变量来分别指定他们的安装目录。 通过RUSTUP_HOME指定…...

机器学习和深度学习综述

机器学习和深度学习综述 1. 人工智能、机器学习、深度学习的关系 近些年人工智能、机器学习和深度学习的概念十分火热,但很多从业者却很难说清它们之间的关系,外行人更是雾里看花。在研究深度学习之前,先从三个概念的正本清源开始。概括来说…...

SQL零基础入门学习(八)

SQL零基础入门学习(七) SQL 连接(JOIN) SQL join 用于把来自两个或多个表的行结合起来。 下图展示了 LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN 相关的 7 种用法。 SQL JOIN SQL JOIN 子句用于把来自两个或多个表的行结合起来,基…...

若依系统如何集成qq邮件发送【超详细,建议收藏】

若依系统的部署博主就不在这儿阐述了,默认大家的电脑已经部署好了若依系统,这里直接开始集成邮件系统,首先我们得需要对qq邮箱进行配置;一套学不会你来打我😀; 一、开启我们的qq邮箱发送邮件的配置 1、先进…...

前端-CSS-zxst

CSS 层叠样式表,为了定义HTML标签的样式 内联样式 在标签内部通过 style 属性设置样式值样式名:样式值;样式名:样式值; 内部样式 在 head 标签内通过 style 标签选择器设置样式,供这个网页上的元素使用 外部样式 在 head 标签内通过 link 标签引入外部…...

合宙Air105|fonts库|mcu.ticks()|LuatOS-SOC接口|官方demo|学习(19):fonts库

基础资料 基于Air105开发板:Air105 - LuatOS 文档 上手:开发上手 - LuatOS 文档 探讨重点 官方fonts库函数介绍以及利用mcu.ticks()计算程序运行周期相关内容的学习及探讨。 软件版本 AIR105:LuatOSAIR105 base 22.12 bsp V0014 32bit …...

成都欢蓬电商:抖音直播卖药灰度测试通告

据报道,近日有MCN机构透露,目前抖音直播卖药为“测试项目,谨慎试跑中”; “仍处于灰度测试,至于测试多久,抖音官方确实没有答复,需要看第一阶段数据,然后定夺,预计4月份会纳入更多机…...

1.1计算机和编成语言

一、C 语言简介历史C 语言最初是作为 Unix 系统的开发工具而发明的。1969年,美国贝尔实验室的肯汤普森(Ken Thompson)与丹尼斯里奇(Dennis Ritchie)一起开发了Unix 操作系统。Unix 是用汇编语言写的,无法移…...

解析 xml 文件 - xml.etree ElementTree

目录1、导入模块 →\rightarrow→ 读取文件 →\rightarrow→ 获取根节点 →\rightarrow→ 获取根节点的标签与属性2、遍历一级子节点、获取子节点的标签 与 属性3、通过索引 获取数据4、Element.findall()、Element.find() - 按照 tag 值查找 子节点5、Element.iter() - 循环迭…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

JavaSec-RCE

简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性&#xff0c…...

XCTF-web-easyupload

试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...