Укажите реализацию метода в impl для трейта с именем метода затенения - PullRequest
0 голосов
/ 06 августа 2020

Учитывая следующий блок trait + impl, как я могу вызвать метод std::vec::Vec * get из реализации для MyMap метода get?

trait MyMap<K, V> {
    fn get(&self, key: &K) -> Option<&V>;
}

impl<V> MyMap<usize, V> for Vec<Option<V>> {
    fn get(&self, key: &usize) -> Option<&V> {
        match Vec::get(self, *key).expect("undersized map") {
            None => None,
            Some(v) => Some(&v),
        }
    }
}

Площадка для ржавчины

Я пробовал:

  • Надеюсь, что компилятор может сделать вывод из моих типов, поскольку они разные: self.get(*key).expect..., что заставляет компилятор разрешать MyMap ' s get и пожаловаться на несовпадение типов.
  • Определение имени типа: Vec::get(self, *key).expect..., что сбивает с толку снова возвращает MyMap get с теми же ошибками, что и self.get
  • Использование Полностью квалифицированного синтаксиса : <Self as Vec>::get(self, *key).expect..., что заставляет компилятор жаловаться на то, что get вообще не существует.
  • Обертывание Vec get в fn за пределами impl блок, который работает, но выглядит очень подозрительно и кажется неправильным решением.

1 Ответ

2 голосов
/ 06 августа 2020

Метод get() для векторов не реализован непосредственно на Vec. Вместо этого это функция среза. Итак, самый простой вариант - сначала разыменовать ваш вектор, получив срез, а затем вызвать get() на этом срезе:

impl<V> MyMap<usize, V> for Vec<Option<V>> {
    fn get(&self, key: &usize) -> Option<&V> {
        match (**self).get(*key).expect("undersized map") {
            None => None,
            Some(v) => Some(&v),
        }
    }
}

Поскольку self имеет тип &Vec<...>, нам нужно дважды разыменовать, чтобы получить срез:

  • При однократном разыменовании мы получаем Vec<Opiton<V>>.
  • При разыменовании снова используется реализация Deref на векторе и получается [Option<V>].

В качестве примечания, тело метода можно упростить с помощью метода Option::as_ref():

fn get(&self, key: &usize) -> Option<&V> {
    (**self).get(*key).expect("undersized map").as_ref()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...