我在学习关联类型时遇到了麻烦。我的问题代码:

trait Fooer {
    fn foo(&self);
}

trait FooStore {
    type T: Fooer;
    fn store_foo(&self, fooer: Self::T);
}

#[allow(dead_code)]
struct DB {}

impl FooStore for DB {
    type T = Fooer;

    fn store_foo(&self, _fooer: Self::T) {}
}

fn main() {}

Play link

这里的目的是使用关联的类型来使FooStore特性不需要impl<F:Fooer, T: FooStore<F>> FooStore<F> for DB的笨拙和有问题的语法,因为它常常提示未使用F

但是,此功能上的official docs显示实现基础关联类型的对象-但不显示特征。在此示例中,DB不知道可能将哪些结构传递给store_foo(..),因此它需要使用特征来解决此问题。

如此说来,如何在impl期间获取关联的类型以使用特征?也就是说,我该如何写type T = Fooer;?还是我以某种方式使用了此错误?

注意:我在构造此示例时遇到了一些麻烦,我现在尝试对其进行更正。我遇到的错误是:
cargo: the trait `Fooer` cannot be made into an object [E0038]

最佳答案



您的结构DB需要为Fooer分配实现FooStore::T的具体类型。 Fooer是一个特征,但也可以用作未定大小的类型。但是,您不能在此处使用未调整大小的类型,因为您无法按值传递未调整大小类型的参数(FooStore::store_foo要求)。

如果您不希望DB将特定类型分配给FooStore::T,则可以使DB通用。

use std::marker::PhantomData;

#[allow(dead_code)]
struct DB<F: Fooer> {
    _phantom: PhantomData<F>,
}

impl<F: Fooer> FooStore for DB<F> {
    type T = F;

    fn store_foo(&self, _fooer: Self::T) {}
}

注意PhantomData的使用:我们使用它来强制使用参数T,它还指示DB<T>从概念上讲拥有T类型的对象。

关于rust - 实现具有关联特征类型的特征,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37246093/

10-10 18:33
查看更多