当尝试在Rust中索引向量时,SliceIndex特征特质绑定了无法满足的错误

时间:2019-06-19 06:30:54

标签: vector indexing rust

我有一个结构:

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 个答案:

答案 0 :(得分:1)

  

Rust似乎在告诉我,我无法使用index(即usize)将向量编入索引。

否,编译器告诉您不能使用&usize为向量建立索引。

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

只需使用*index即可解决此特定问题。但是,您的代码也有其他问题:

  • Index特征需要一个类型参数,例如&str
  • index()方法通常只能返回对要建立索引的数据结构中存储的数据的引用。您的代码创建了一个临时Option,该临时变量未存储在原始数据中,然后尝试返回对此的引用。如果要执行此操作,则需要定义自己的方法(或特征),该方法将按值返回Option

答案 1 :(得分:1)

也许编译器错误很难理解,但至少是准确的。它告诉您index是引用&usize,但是Vec只能用值usize进行索引。因此,您要做的就是取消引用index

此外,如果找不到键/索引,通常会索引panic。 (这就是为什么标准库将Vec::getHashMap::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),
            }
        }
    }
}