在Rust里,我们一般倾向于为一个具体的类型实现实现trait,然而,还有一种鲜为人知的写法,为泛型实现trait。分为trait object和带有trait constraint的泛型参数两种。
impl trait for trait object
定义traitX
,Y
和一个简单的结构体A
trait X {
fn say_hello(&self);
}
trait Y {
fn say_yes(&self);
}
struct A(String);
然后可以为trait X
object实现traitY
impl Y for dyn X {
fn say_yes(&self) {
println!("Yes");
}
}
要想使用这个say_yes
方法,先为A
实现traitX
impl X for A {
fn say_hello(&self) {
println!("Hello, {}", self.0);
}
}
然后试试看
fn main() {
let a: &dyn X = &A("TENX".to_string());
a.say_yes();
}
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/demo1`
Yes
impl trait for trait constraint
与上面一样,先定义两个traitA
,B
trait A {
fn say_hello();
}
trait B {
type T;
fn f() -> Self::T;
}
然后可以为一个带有constraint的泛型参数X
实现traitA
impl<X> A for X
where X: B,
X::T: std::fmt::Display,
{
fn say_hello() {
println!("hello, {}", X::f());
}
}
要使用say_hello
,我们先为一个具体的类型实现traitB
,注意,associate type必须还满足constraint: std::fmt::Display
struct Foo;
impl B for Foo {
type T = String;
fn f() -> String {
"TENX".to_string()
}
}
测试一下
fn main() {
Foo::say_hello();
}
> cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.11s
Running `target/debug/demo2`
hello, TENX
作用
作用的话?类似于patch?但是为什么不直接在原本的trait里做呢。
网友评论