如何从结构中预定义的“Range”访问切片?

时间:2017-02-23 10:27:31

标签: rust slice

使用切片语法访问切片非常简单:slice = vector[i..j]

在存储范围的情况下,我可以告诉你不能这样做:

struct StructWithRange {
    range: std::ops::Range<usize>,
}

fn test_slice(s: &StructWithRange, vector: &Vec<i32>) {
    let slice = &vector[s.range];
    println!("{:?}", slice); // prints [2, 3]
}

fn main() {
    let vector = vec![1,2,3,4,5];
    let s = StructWithRange {
        range: 1..3
    };

    test_slice(&s, &vector);
}

这给出了错误:

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:6:25
  |
6 |     let slice = &vector[s.range];
  |                         ^ cannot move out of borrowed content

有没有办法从范围中获取切片而不扩展它?例如:vector[s.range.start..s.range.end]

如果结构中的usize可以用于索引查找,为什么不能以相同的方式使用Range<usize>

2 个答案:

答案 0 :(得分:5)

由于Index是需要以下功能的特性:

fn index(&self, index: Idx) -> &Self::Output

它消耗/移动用于索引的值(index)。在您的情况下,您尝试使用借用的结构中的Range来索引切片,但由于您只传递了引用,并且范围没有实现Copy,因此会失败。

您可以通过以下方式解决问题:将test_slice的定义更改为消费StructWithRangeclone()索引中的s.range

答案 1 :(得分:3)

出现错误消息是因为Range未实现CopyIndex使用其索引。

可以通过添加对.clone()的调用来解决:&vector[s.range.clone()]

如果您check the code,它会链接到被拒绝的提案,以便在其参数为Copy here的情况下将Range添加到Copy

拒绝原因是:

  

这些没有它,因为它们是迭代器。

     

选择删除Copy impls而不是调整for loop desugaring或linting是为了防止这种有问题的情况:

let mut iter = 0..n;
for i in iter { if i > 2 { break; } }
iter.collect()
     

这里实际上并没有变异,而是复制了。需要for i in &mut iter来改变迭代器。

     

我们可以在通过for循环复制之后切换到使用迭代器变量的linting,但是没有做出决定。