rust - 我可以有条件地提供特征函数的默认实现吗?

标签 rust

我有以下特点:

trait MyTrait {
    type A;
    type B;

    fn foo(a: Self::A) -> Self::B;

    fn bar(&self);
}

bar 等其他函数必须始终由特征的用户实现。

我想给 foo 一个默认实现,但只有当类型 A = B 时。

伪 Rust 代码:

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 中可能吗?

最佳答案

您可以通过引入冗余类型参数在特征定义本身中提供默认实现:

trait MyTrait {
    type A;
    type B;

    fn foo<T>(a: Self::A) -> Self::B
    where
        Self: MyTrait<A = T, B = T>,
    {
        a
    }
}

可以为个别类型覆盖此默认实现。但是,专用版本将从特征上的 foo() 定义继承特征绑定(bind),因此您只能在 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 ,但我不认为它可以用来实现你想要的。

关于rust - 我可以有条件地提供特征函数的默认实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55628334/

相关文章:

rust - 从 Option 借来的 RefMut 生命周期不够长 (Option<Rc<RefCell<Node>>>)

rust - 我应该如何重组图形代码以避免出现 "Cannot borrow variable as mutable more than once at a time"错误?

linker - 通过使用内联汇编的 Raspberry Pi3 的 Rust 启动代码

arrays - 如何将数组强制转换为匹配臂中的切片?

serialization - 序列化未实现序列化的外部 crate 枚举的 vec

rust - 无法设置按钮颜色

rust - 如何遍历(巨大)压缩文件的行?

iterator - 如何使用同一个迭代器两次,一次用于计数,一次用于迭代?

rust - 如何在Rust数组的2个可变切片上进行操作?

c++ - 将调用 C++ 的 Rust 编译为 WASM