如何使用可变Vec中的切片作为HashMap中的键

时间:2019-07-12 07:08:29

标签: rust

我正在尝试实现一个简单的程序,该程序将短序列(let sample: Vec<u32>)存储在主向量(let mut samplesTable: Vec<Vec<u32>>)中 并具有将序列映射到主向量中其对应索引的搜索索引。

序列代表某些实验的统计样本。我需要能够通过其内容找到样本的ID(samplesTable中的索引)。

内存要求很高,因此程序的体系结构可以更好地避免冗余。 因此,搜索索引只是一个HashMap<&[u32], u32>,其中第一个参数是samplesTable中样本的完整切片,第二个参数是该样本的相应索引。

下一步将是多线程版本。

这种模式对我来说非常重要,因此我必须找到一种在Rust中实现它的方法。


到目前为止,我已经尝试过:

  1. addSample的所有呼叫站点包裹在“ {}”中以创建另一个作用域。
  2. 切换到每晚并强制#![feature(nll)]

我正在使用Windows 7和Rust版本1.35和1.36。

我没有使用外部包装箱,这是一个普通的“新货--bin”。

use std::collections::HashMap;

// Adds new sample to the table with the given index and updates index map.
// If there is an old sample, we insert the new sample with the 'id' from the old one.
// In this case 'id; parameter is should be zero and ignored in the function.
fn addSample<'a, 'b: 'a>(
    oldSample: Option<Vec<u32>>,
    newSample: Vec<u32>,
    id: u32,
    samplesTable: &'b mut Vec<Vec<u32>>,
    indexMap: &'a mut HashMap<&'a [u32], u32>,
) {
    // We have the oldSample, then replace it with the new one
    if let Some(oldSampleTmp) = oldSample {
        let oldID = indexMap.remove(oldSampleTmp.as_slice());

        if let Some(oldId) = oldID {
            samplesTable[oldId as usize] = newSample;

            let slice: &[u32] = samplesTable[oldId as usize].as_slice();
            indexMap.insert(slice, oldId);
        } else {
            panic!(
                "addSample: oldSampleTmp was not found!\n  oldSampleTmp={:?}",
                oldSampleTmp
            )
        };
    }
    // We don't have the oldSample, so just insert newSample with provided 'id'
    else {
        samplesTable[id as usize] = newSample;

        let slice: &[u32] = samplesTable[id as usize].as_slice();
        indexMap.insert(slice, id);
    }
} // end of the "addSample" function

fn main() {
    // init our tables
    let mut indexMap: HashMap<&[u32], u32> = HashMap::new();

    let mut samplesTable: Vec<Vec<u32>> = Vec::with_capacity(3);

    // prepare the sample data
    let sampleA: Vec<u32> = vec![1, 2, 3];
    let sampleB: Vec<u32> = vec![4, 5, 6];
    let sampleC: Vec<u32> = vec![7, 8, 9];

    // trying to fill the tables
    addSample(None, sampleA, 1, &mut samplesTable, &mut indexMap);
    addSample(None, sampleB, 2, &mut samplesTable, &mut indexMap);
    addSample(None, sampleC, 3, &mut samplesTable, &mut indexMap);

    // debug print
    println!("indexMap is {:?}", &indexMap);
    println!("index is {:?}", indexMap.get(vec![1, 2, 3].as_slice()));
}

问题是Rust会产生此错误:

  

错误[E0499]:一次不能多次借用samplesTable作为可变变量

据我了解,所有修改都包含在“ addSample”的主体中。 因此,在第一次通话后,相同范围内的其他通话应该没有问题。

0 个答案:

没有答案