此外,trait还可以作为函数的参数,也就是需要传入一个实现了对应trait的结构体的实例。
pub fn notify(item: impl Summary) { println!("Breaking news! {}", item.summarize()); }作参数时,我们需要使用impl关键字来定义参数类型。
Rust还提供了另一种语法糖来,即Trait限定,我们可以使用泛型约束的语法来限定Trait参数。
pub fn notify<T: Summary>(item: T) { println!("Breaking news! {}", item.summarize()); }如上述代码,我们可以通过Trait来限定泛型T的范围。这样的语法糖可以在多个参数的函数中帮助我们简化代码。下面两行代码就有比较明显的对比
pub fn notify(item1: impl Summary, item2: impl Summary) { pub fn notify<T: Summary>(item1: T, item2: T) {如果某个参数有多个trait限定,就可以使用+来表示
pub fn notify<T: Summary + Display>(item: T) {如果我们有更多的参数,并且有每个参数都有多个trait限定,及时我们使用了上面这种语法糖,代码仍然有些繁杂,会降低可读性。所以Rust又为我们提供了where关键字。
fn some_function<T, U>(t: T, u: U) -> i32 where T: Display + Clone, U: Clone + Debug {它帮助我们在函数定义的最后写一个trait限定列表,这样可以使代码的可读性更高。
Trait作为返回值 fn returns_summarizable() -> impl Summary { Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, } }Trait作为返回值类型,和作为参数类似,只需要在定义返回类型时使用impl Trait。
总结本文我们简单介绍了泛型和Trait,包括它们的定义和使用方法。泛型主要是针对数据类型的一种抽象,而Trait则是对数据类型行为的一种抽象,Rust中并没有严格意义上的继承,多是用组合的形式。这也体现了「多组合,少继承」的设计思想。
最后留个预告,这个坑还没完,我们下次继续往深处挖。