Reputation: 367
I'm having trouble learning about associated types. My problem code:
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() {}
The intent here is to use associated types to make the FooStore
trait not require the awkward and problematic syntax of impl<F:Fooer, T: FooStore<F>> FooStore<F> for DB
because that often complains about F
not being used.
However, the official docs on this feature show objects implementing the underlying associated type - but not traits. In this example, DB
does not know what structs might be passed into store_foo(..)
, so it needs to use a trait to solve this issue.
With that said, how can I get an associated type to use a trait during impl
? That is, how can I write type T = Fooer;
? Or am I using this wrong somehow?
Note: I'm having some trouble constructing this example, I'm trying to correct this now. The error I was having is:
cargo: the trait `Fooer` cannot be made into an object [E0038]
Upvotes: 2
Views: 483
Reputation: 65657
The intent here is to use associated types to make the
FooStore
trait not require the awkward and problematic syntax ofimpl<F:Fooer, T: FooStore<F>> FooStore<F> for DB
because that often complains aboutF
not being used.
Your struct DB
needs to assign a concrete type that implements Fooer
to FooStore::T
. Fooer
is a trait, but can also be used as an unsized type. However, you can't use an unsized type here, because you can't pass an argument of an unsized type by value (which FooStore::store_foo
requires).
If you don't want DB
to assign a particular type to FooStore::T
, then you can make DB
generic.
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) {}
}
Notice the use of PhantomData
: we use it to force the parameter T
to be used, and it also indicates that DB<T>
conceptually owns objects of type T
.
Upvotes: 3