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”。
这时候,我们就有必要使用完整的函数调用语法来进行方法调用,只有这样写,才能清晰明白且无歧义地表达清楚期望调用的是哪个函数:文章来源:https://www.toymoban.com/news/detail-809432.html
文章来源地址https://www.toymoban.com/news/detail-809432.html
到了这里,关于Rust-trait的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!