trait:定义共享的行为
ch10-02-traits.md
commit 709eb1eaca48864fafd9263042f5f9d9d6ffe08d
trait 允许我们进行另一种抽象:他们让我们可以抽象类型所通用的行为。trait 告诉 Rust 编译器某个特定类型拥有可能与其他类型共享的功能。在使用泛型类型参数的场景中,可以使用 trait bounds 在编译时指定泛型可以是任何实现了某个 trait 的类型,并由此在这个场景下拥有我们希望的功能。
注意:trait 类似于其他语言中的常被称为接口(interfaces)的功能,虽然有一些不同。
定义 trait
一个类型的行为由其可供调用的方法构成。如果可以对不同类型调用相同的方法的话,这些类型就可以共享相同的行为了。trait 定义是一种将方法签名组合起来的方法,目的是定义一个实现某些目的所必须行为的集合。
例如,这里有多个存放了不同类型和属性文本的结构体:结构体NewsArticle
用于存放发生于世界各地的新闻故事,而结构体Tweet
最多只能存放 140 个字符的内容,以及像是否转推或是否是对推友的回复这样的元数据。
我们想要创建一个多媒体聚合库用来显示可能储存在NewsArticle
或Tweet
实例中的数据的总结。每一个结构体都需要的行为是他们是能够被总结的,这样的话就可以调用实例的summary
方法来请求总结。列表 10-11 中展示了一个表现这个概念的Summarizable
trait 的定义:
使用trait
关键字来定义一个 trait,后面是 trait 的名字,在这个例子中是Summarizable
。在大括号中声明描述实现这个 trait 的类型所需要的行为的方法签名,在这个例子中是是fn summary(&self) -> String
。在方法签名后跟分号而不是在大括号中提供其实现。接着每一个实现这个 trait 的类型都需要提供其自定义行为的方法体,编译器也会确保任何实现Summarizable
trait 的类型都拥有与这个签名的定义完全一致的summary
方法。
trait 体中可以有多个方法,一行一个方法签名且都以分号结尾。
为类型实现 trait
现在我们定义了Summarizable
trait,接着就可以在多媒体聚合库中需要拥有这个行为的类型上实现它了。列表 10-12 中展示了NewsArticle
结构体上Summarizable
trait 的一个实现,它使用标题、作者和创建的位置作为summary
的返回值。对于Tweet
结构体,我们选择将summary
定义为用户名后跟推文的全部文本作为返回值,并假设推文内容已经被限制为 140 字符以内。
在类型上实现 trait 类似与实现与 trait 无关的方法。区别在于impl
关键字之后,我们提供需要实现 trait 的名称,接着是for
和需要实现 trait 的类型的名称。