我在学习关联类型时遇到了麻烦。我的问题代码:
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/