Ошибка SliceIndex связана с неудовлетворенной ошибкой при попытке индексирования в вектор в Rust - PullRequest
0 голосов
/ 19 июня 2019

У меня есть структура:

pub struct SomeCollection<'a> {
    items: Vec<&'a SomeValue>,
    name_mapping: HashMap<&'a str, usize>,
    index_mapping: HashMap<&'a str, usize>
}

impl<'a> Index for SomeCollection<'a> {
    type Output = Option<&'a SomeValue>;

    fn index(&self, value_name: &str) -> &Self::Output {
        match self.name_mapping.get(value_name) {
            Some(index) => &self.items.get(index),
            None => match self.index_mapping.get(value_name) {
                Some(index) => &self.items.get(index),
                None => &None
            }
        }
    }
}

Когда я пытаюсь скомпилировать этот код, я получаю следующую ошибку:

error[E0277]: the trait bound `&usize: std::slice::SliceIndex<[&SomeValue]>` is not satisfied
  --> src\some_collection.rs:49:48
   |
49 |                 Some(index) => &self.items.get(index),
   |                                            ^^^ slice indices are of 
type `usize` or ranges of `usize`
   |
   = help: the trait `std::slice::SliceIndex<[&SomeValue]>` is not implemented for `&usize`

Кажется, что Rust говорит мне, что я не могу индексироватьв вектор с index, который является usize.Я не уверен, почему мне нужно реализовать эту черту, поскольку она должна быть реализована для вектора по умолчанию.Может ли кто-нибудь объяснить мне истинную причину, по которой я получаю эту ошибку?В этом коде могут быть другие ошибки, которые еще не появились, поэтому имейте это в виду при ответе.

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Может быть, ошибку компилятора трудно понять, но, по крайней мере, она точна. Он говорит вам, что index является ссылкой &usize, однако Vec может быть проиндексирован только со значением usize. Так что все, что вам нужно сделать, это разыменование index.

Более того, обычно индексирование panic с, если ключ / индекс не может быть найден. (Вот почему стандартная библиотека предлагает Vec::get и HashMap::get в качестве отдельных методов наряду с индексацией, которые не panic, но возвращают None, если данный ключ / индекс отсутствует в коллекции.)

impl<'a> Index<&str> for SomeCollection<'a> {
    type Output = &'a SomeValue;

    fn index(&self, value_name: &str) -> &Self::Output {
        match self.name_mapping.get(value_name) {
            Some(index) => &self.items[*index],
            None => match self.index_mapping.get(value_name) {
                Some(index) => &self.items[*index],
                None => panic!("Missing key: {:?}", value_name),
            }
        }
    }
}
1 голос
/ 19 июня 2019

Руст, кажется, говорит мне, что я не могу индексировать вектор с index, то есть usize.

Нет, компилятор говорит вам, что вы не можете индексировать вектор с &usize.

the trait `std::slice::SliceIndex<[&SomeValue]>` is not implemented for `&usize`

Простое использование *index вместо этого решит эту конкретную проблему. Однако у вашего кода есть и другие проблемы:

  • Черта Index нуждается в параметре типа, например, &str в этом случае.
  • Метод index() обычно может возвращать только ссылку на данные, хранящиеся в индексируемой структуре данных. Ваш код создает временное Option, которое не сохраняется в исходных данных, а затем пытается вернуть ссылку на это. Если это то, что вы хотите сделать, вам нужно определить свой собственный метод (или черту), который вместо этого возвращает Option по значению.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...