I have a little nuisance in my project, that I can't resolve: The compiler doesn't see that the associated type is the same as the concrete type and won't let my do an assignement.
Does anyone know how to fix it. Thank you for taking your time.
Artos
// This program fails to compile
// Compiler doesn't see that the associated type and type of user id are the same.
struct User {
pub id: u64,
}
trait KeyTrait {
type Key;
fn key(&self) -> Self::Key;
}
impl KeyTrait for User {
type Key = u64;
fn key(&self) -> Self::Key {
self.id
}
}
trait PrintTrait {
fn print_key<K: KeyTrait>(key: K);
}
impl PrintTrait for User {
fn print_key<K: KeyTrait>(key_impl: K) {
let id: u64 = key_impl.key(); // Raises error: expected u64, found associated type
println!("Found key {}", id);
}
}
fn main() {
let user = User { id: 5 };
User::print_key(user);
}
This code makes the assumption that every implementation of KeyTrait
has the same associated Key
type.
impl PrintTrait for User {
fn print_key<K: KeyTrait>(key_impl: K) {
let id: u64 = key_impl.key();
println!("Found key {}", id);
}
}
In fact, an implementation of KeyTrait
could choose any type.
You can encode this assumption in the type system:
trait PrintTrait {
fn print_key<K>(key: K)
where
K: KeyTrait<Key = u64>;
}
impl PrintTrait for User {
fn print_key<K>(key_impl: K)
where
K: KeyTrait<Key = u64>,
{
let id: u64 = key_impl.key();
}
}
Or, if you need PrintTrait
to be generic over all possible associated Key
types:
trait PrintTrait<T> {
fn print_key<K>(key: K)
where
K: KeyTrait<Key = T>;
}
impl PrintTrait<u64> for User {
fn print_key<K>(key_impl: K)
where
K: KeyTrait<Key = u64>,
{
let id: u64 = key_impl.key();
}
}