【问题标题】:How to use the outer type for a generic type parameter in trait impls如何在 trait impls 中将外部类型用于泛型类型参数
【发布时间】:2021-08-10 01:08:53
【问题描述】:

我有一个最小的例子如下。

有两个特征,TraitATraitBTraitB 有一个通用函数,它使用 TraitA 作为类型参数。 TraitB 必须是对象安全的,所以我用where Self: Sized 标记函数。到目前为止它运行良好。

如果我有一个结构MyStruct<A: TraitA>,并且我想为它实现TraitBimpl 块将具有 impl<A: TraitA> TraitB for MyStruct<A>。但是对于generic_func,编译器抱怨A 已经被使用了。我无法编译代码,因为我不知道用什么代替“???”在示例中。

use std::marker::PhantomData;

// One trait
trait TraitA {}

// The other trait that has one generic function that uses TraitA
trait TraitB {
    fn generic_func<A: TraitA>(self) where Self: Sized;
}

// TraitB needs to be object safe
fn foo(a: &dyn TraitB) {
    
}

// The generic struct that uses TraitA, but needs to implement TraitB as well.
struct MyStruct<A: TraitA>(PhantomData<A>);

impl<A: TraitA> TraitB for MyStruct<A> {
    // What should I put as ???. It should refer to A.
    fn generic_func<???>(self) where Self: Sized {
    }
}

Rust 游乐场链接:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=4eff9e5a6fded93e03a090890f84e983

【问题讨论】:

    标签: generics rust traits


    【解决方案1】:

    任何字母都可以。 CDPotato 等,Rust 不在乎泛型变量是否具有相同的名称,只是它们的使用方式相同(即无论你名字必须是: TraitA)

    impl<A: TraitA> TraitB for MyStruct<A> {
      fn generic_func<Potato: TraitA>(self) where Self: Sized {
      }
    }
    

    正如您所写,TraitB 需要一个适用于实现TraitA每个 类型的generic_func。如果您希望它适用于特定的人,则需要以不同的方式编写您的特质。

    trait TraitB {
      type MyA: TraitA;
      fn generic_func(self);
    }
    
    impl<A: Trait> TraitB for MyStruct<A> {
      type MyA = A;
      fn generic_func(self) { ... }
    }
    

    现在,在 trait 内部,Self::MyA 指的是特定类型,您正在实现此 trait 以使用它。

    【讨论】:

    • 是的。但是有没有办法确保泛型函数的类型参数与结构的类型参数相同? (即Potato 与示例中的A 相同)
    • 查看我的编辑。当您编写 trait 时,generic_func 必须适用于 所有 有效类型。如果这不是您想要的,您可以更改您的特征定义。
    猜你喜欢
    • 2011-01-01
    • 2023-03-06
    • 1970-01-01
    • 2015-08-07
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多