【问题标题】:How to access a slice from pre-defined 'Range' in a struct?如何从结构中的预定义“范围”访问切片?
【发布时间】:2017-07-13 18:34:41
【问题描述】:

使用切片语法访问切片很简单: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&lt;usize&gt;

【问题讨论】:

  • 请发布minimal reproducible example,因为它应该可以工作,但如果没有明确的示例,很难理解您未显示的代码可能有什么问题。此 MCVE 还应包括您从编译器获得的错误消息。

标签: rust slice


【解决方案1】:

由于Index 是一个需要以下函数的特征:

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

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

您可以通过例如修复它将test_slice 的定义更改为使用索引中的StructWithRangeclone() 使用s.range

【讨论】:

    【解决方案2】:

    出现错误消息是因为Range 没有实现Copy 并且Index 消耗了它的索引。

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


    如果你check the code,则在其参数为Copyhere的情况下,它链接到被拒绝的提议,将Copy添加到Range

    拒绝原因是:

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

    选择删除 Copy impls 而不是为循环脱糖或 linting 进行调整是为了防止这种有问题的情况:

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

    这里的 iter 实际上并没有发生变异,而是被复制了。 for i in &amp;mut iter 是改变迭代器所必需的。

    在迭代器变量被 for 循环复制后,我们可以转而使用 linting,但没有决定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 2021-01-10
      • 2013-07-27
      • 1970-01-01
      • 2020-10-24
      • 2020-07-08
      相关资源
      最近更新 更多