Rust-trait

Rust语言中的trait是非常重要的概念。

在Rust中,trait这一个概念承担了多种职责。在中文里,trait可以翻译为"特征""特点""特性"等。

成员方法

trait中可以定义函数。用例子来说明,我们定义如下的trait:

上面这个trait包含了一个方法,这个方法只有一个参数,这个&self参数是什么意思呢?

所有的trait中都有一个隐藏的类型Self(大写S),代表当前这个实现了此trait的具体类型。trait中定义的函数,也可以称作关联函数(associated function)。

函数的第一个参数如果是Self相关的类型,且命名为self(小写s),这个参数可以被称为"receiver"(接收者)。具有receiver参数的函数,我们称为"方法"(method),可以通过变量实例使用小数点来调用。

没有receiver参数的函数,我们称为"静态函数"(static function),可以通过类型加双冒号::的方式来调用。在Rust中,函数和方法没有本质区别。

Rust中Self(大写S)和self(小写s)都是关键字,大写S的是类型名,小写s的是变量名。请大家一定注意区分。self参数同样也可以指定类型,当然这个类型是有限制的,必须是包装在Self类型之上的类型。

对于第一个self参数,常见的类型有self :Self、self:&Self、self :&mut Self等类型。对于以上这些类型,Rust提供了一种简化的写法,我们可以将参数简写为self、&self、&mut self。

self参数只能用在第一个参数的位置。请注意"变量self"和"类型Self"的大小写不同。示例如下:

所以,回到开始定义的那个Shape trait,上面定义的这个area方法的参数的名字为self,它的类型是αSelf类型。我们可以把上面这个方法的声明看成:

我们可以为某些具体类型实现(impl)这个trait。

假如我们有一个结构体类型Circle,它实现了这个trait,代码如下:

另外,针对一个类型,我们可以直接对它impl来增加成员方法,无须trait名字。比如:

静态方法

没有receiver参数的方法(第一个参数不是self参数的方法)称作"静态方法"。静态方法可以通过Type::FunctionName()的方式调用。需要注意的是,即便我们的第一个参数是Self相关类型,只要变量名字不是self,就不能使用小数点的语法调用函数。

扩展方法

我们还可以利用trait给其他的类型添加成员方法,哪怕这个类型不是我们自己写的。比如,我们可以为内置类型i32添加一个方法:

完整函数调用语法

Fully Qualified Syntax提供一种无歧义的函数调用语法,允许程序员精确地指定想调用的是那个函数。

以前也叫UFCS(universal function call syntax),也就是所谓的"通用函数调用语法"。

这个语法可以允许使用类似的写法精确调用任何方法,包括成员方法和静态方法。

其他一切函数调用语法都是它的某种简略形式。它的具体写法为::item。示例如下:

我们定义了两个trait,它们的start()函数有同样方法签名。

如果一个类型同时实现了这两个trait,那么如果我们使用variable.start()这样的语法执行方法调用的话,就会出现歧义,编译器不知道你具体想调用哪个方法,编译错误信息为"multiple applicable items in scope"。

这时候,我们就有必要使用完整的函数调用语法来进行方法调用,只有这样写,才能清晰明白且无歧义地表达清楚期望调用的是哪个函数:

相关推荐
陈随易1 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
布莱克6053 小时前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
云-缩影3 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
LabVIEW开发3 小时前
LabVIEW 局部变量为何引发竞争条件?四种同步机制
开发语言·labview
benchmark_cc3 小时前
A 股、港股、美股如何建立统一的标的主数据格式?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
考虑考虑4 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
无奈何杨4 小时前
风控决策系统决策流,策略模式,权重、顺序、投票、最坏
后端
Zenova EdgeOS5 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
取名真是5 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
FRing035 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2