使用切片语法访问切片非常简单: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>
?
答案 0 :(得分:5)
由于Index
是需要以下功能的特性:
fn index(&self, index: Idx) -> &Self::Output
它消耗/移动用于索引的值(index
)。在您的情况下,您尝试使用借用的结构中的Range
来索引切片,但由于您只传递了引用,并且范围没有实现Copy
,因此会失败。
您可以通过以下方式解决问题:将test_slice
的定义更改为消费StructWithRange
或clone()
索引中的s.range
。
答案 1 :(得分:3)
出现错误消息是因为Range
未实现Copy
且Index
使用其索引。
可以通过添加对.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,但是没有做出决定。