我具有以下特征:
trait MyTrait {
type A;
type B;
fn foo(a: Self::A) -> Self::B;
fn bar(&self);
}
特征bar
等其他功能必须始终由特征用户来实现。
我想为foo
提供一个默认实现,但仅当类型为A = B
时。
伪锈代码:
impl??? MyTrait where Self::A = Self::B ??? {
fn foo(a: Self::A) -> Self::B {
a
}
}
这可能:
struct S1 {}
impl MyTrait for S1 {
type A = u32;
type B = f32;
// `A` is different from `B`, so I have to implement `foo`
fn foo(a: u32) -> f32 {
a as f32
}
fn bar(&self) {
println!("S1::bar");
}
}
struct S2 {}
impl MyTrait for S2 {
type A = u32;
type B = u32;
// `A` is the same as `B`, so I don't have to implement `foo`,
// it uses the default impl
fn bar(&self) {
println!("S2::bar");
}
}
在Rust中有可能吗?
答案 0 :(得分:3)
您可以通过引入冗余类型参数在trait定义本身中提供默认实现:
trait MyTrait {
type A;
type B;
fn foo<T>(a: Self::A) -> Self::B
where
Self: MyTrait<A = T, B = T>,
{
a
}
}
可以为单个类型覆盖此默认实现。但是,专用版本将继承特征上的foo()
定义所绑定的特征,因此只有A == B
时,您才可以调用该方法:
struct S1;
impl MyTrait for S1 {
type A = u32;
type B = f32;
fn foo<T>(a: Self::A) -> Self::B {
a as f32
}
}
struct S2;
impl MyTrait for S2 {
type A = u32;
type B = u32;
}
fn main() {
S1::foo(42); // Fails with compiler error
S2::foo(42); // Works fine
}
Rust也有一个unstable impl specialization feature,但我认为它不能用于实现您想要的功能。
答案 1 :(得分:2)
足够了吗?:
trait MyTrait {
type A;
type B;
fn foo(a: Self::A) -> Self::B;
}
trait MyTraitId {
type AB;
}
impl<P> MyTrait for P
where
P: MyTraitId
{
type A = P::AB;
type B = P::AB;
fn foo(a: Self::A) -> Self::B {
a
}
}
struct S2;
impl MyTraitId for S2 {
type AB = i32;
}
如前所述,如果MyTrait
和其他MyTraitId
无法为其提供实现的方法一样,就会出现问题。
答案 2 :(得分:0)
扩展user31601's answer并使用Sven Marnach的评论,这是使用“委托方法”模式的trait的附加功能实现:
trait MyTrait {
type A;
type B;
fn foo(a: Self::A) -> Self::B;
fn bar();
}
trait MyTraitId {
type AB;
fn bar_delegate();
}
impl<P> MyTrait for P
where
P: MyTraitId,
{
type A = P::AB;
type B = P::AB;
fn foo(a: Self::A) -> Self::B {
a
}
fn bar() {
<Self as MyTraitId>::bar_delegate();
}
}
struct S2;
impl MyTraitId for S2 {
type AB = i32;
fn bar_delegate() {
println!("bar called");
}
}
fn main() {
<S2 as MyTrait>::bar(); // prints "bar called"
}