Компилятор не видит тип ассоциатов, такой же как конкретный тип - PullRequest
1 голос
/ 18 октября 2019

У меня есть небольшая неприятность в моем проекте, которую я не могу устранить: компилятор не видит, что связанный тип совпадает с конкретным типом, и не позволяет my выполнять назначение.

Детская площадка

Кто-нибудь знает, как это исправить. Спасибо, что нашли время.

Артос

// 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);
}

1 Ответ

1 голос
/ 18 октября 2019

Этот код предполагает, что каждая реализация KeyTrait имеет один и тот же связанный Key тип.

impl PrintTrait for User {
    fn print_key<K: KeyTrait>(key_impl: K) {
        let id: u64 = key_impl.key();
        println!("Found key {}", id);
    }
}

Фактически, реализация KeyTrait может выбиратьлюбой тип.

Вы можете закодировать это предположение в системе типов:

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();
    }
}

Или, если вам нужно, чтобы PrintTrait был универсальным для всех возможных связанных Key типов:

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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...