Rust 我可以有条件地提供trait函数的默认实现吗?
我有以下特点:Rust 我可以有条件地提供trait函数的默认实现吗?,rust,Rust,我有以下特点: trait-MyTrait{ A型; B型; fn foo(a:Self::a)->Self::B; fn-bar(和self); } 还有一些其他功能,如bar,必须始终由trait的用户实现 我想为foo提供一个默认实现,但仅当类型a=B时 伪锈代码: impl???我的特质,其中Self::A=Self::B???{ fn foo(a:Self::a)->Self::B{ A. } } 这是可能的: structs1{} S1的impl-MyTrait{ A型=u32;
trait-MyTrait{
A型;
B型;
fn foo(a:Self::a)->Self::B;
fn-bar(和self);
}
还有一些其他功能,如bar
,必须始终由trait的用户实现
我想为foo
提供一个默认实现,但仅当类型a=B
时
伪锈代码:
impl???我的特质,其中Self::A=Self::B???{
fn foo(a:Self::a)->Self::B{
A.
}
}
这是可能的:
structs1{}
S1的impl-MyTrait{
A型=u32;
B型=f32;
//'A'与'B'不同,因此我必须实现'foo'`
fn foo(a:u32)->f32{
a为f32
}
fn条(&self){
println!(“S1::bar”);
}
}
结构S2{}
S2的impl-MyTrait{
A型=u32;
B型=u32;
//'A'与'B'相同,因此我不必实现'foo',
//它使用默认的impl
fn条(&self){
println!(“S2::bar”);
}
}
这在Rust中可能吗?您可以通过引入冗余类型参数在特征定义本身中提供默认实现:
trait MyTrait {
type A;
type B;
fn foo<T>(a: Self::A) -> Self::B
where
Self: MyTrait<A = T, B = T>,
{
a
}
}
生锈也有一个原因,但我认为它不能用来实现你想要的东西。这就足够了吗
trait-MyTrait{
A型;
B型;
fn foo(a:Self::a)->Self::B;
}
特征粘虫{
AB型;
}
implMyTrait for P
哪里
P:MyTraitId
{
A型=P::AB;
B型=P::AB;
fn foo(a:Self::a)->Self::B{
A.
}
}
结构S2;
S2的impl-MyTraitId{
AB型=i32;
}
如前所述,如果MyTrait
和其他MyTraitId
无法提供实现的方法一样,它会遇到问题。扩展并使用Sven Marnach评论中的注释,下面是使用“委托方法”模式实现trait的附加功能:
trait-MyTrait{
A型;
B型;
fn foo(a:Self::a)->Self::B;
fn-bar();
}
特征粘虫{
AB型;
fn bar_delegate();
}
implMyTrait for P
哪里
P:MyTraitId,
{
A型=P::AB;
B型=P::AB;
fn foo(a:Self::a)->Self::B{
A.
}
fn bar(){
::bar_delegate();
}
}
结构S2;
S2的impl-MyTraitId{
AB型=i32;
fn bar_代表(){
println!(“被称为酒吧”);
}
}
fn main(){
::bar();//打印“bar called”
}
问题在于,对于任何类型的
p
,都可能有多个MyTraitId
实现,因此,对于MyTrait
,您最终会遇到多个冲突impl。通过使T
成为MyTraitId
的关联类型而不是类型参数,可以实现这一点,但这仍然只是部分解决方案,因为您必须在一揽子实现中实现MyTrait
的所有方法。请不要发布未经测试的代码。相反,使用它可以轻松快速地检查代码。这使您和我们的生活变得更加轻松:)这会起作用,但是如果trait中还有其他没有默认实现的函数呢?最初我有评论指出还有其他功能,现在我编辑了我的问题,并添加了第二个功能以澄清问题。你为什么再次在问题中添加“其他方法”?这真的很重要吗?@嘿,这很可能很重要。举个例子,另一个答案中的代码的固定版本实际上适用于没有任何进一步方法的情况,但在其他情况下会变得很麻烦。谢谢,但由于您已经描述的原因,此解决方案不适用于我-如果A!=B
,即使您提供了自己的foo
实现。在尝试回答时,我遇到了可能感兴趣的问题。trait中不接受self
(或引用它)或返回self
的函数有意义吗?@Cerberus我想没有,但这只是一个简化的例子。我将对其进行编辑以使其更有意义。
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
}