2017-02-23 27 views
2

訪問片是直接使用切片語法:slice = vector[i..j]如何從結構中的預定義'Range'訪問切片?

的情況下的範圍內不論如何儲存,從我可以告訴你不能做的:

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

請發表[MCVE],因爲它應該工作,但沒有一個明顯的例子,這是很難理解什麼是可能錯了代碼,你沒有顯示。此MCVE還應該包含從編譯器獲得的錯誤消息。 –

回答

3

由於Range未執行CopyIndex消耗其索引,因此會出現錯誤消息。

可以通過添加.clone()的呼叫來解決:&vector[s.range.clone()]


如果你check the code,它鏈接到被拒絕的建議的情況下添加CopyRange,其中它的參數是Copyhere

的拒絕理由是:

These don't have it because they're iterators.

The choice of removing Copy impls instead of adjusted for loop desugaring or linting was made to prevent this problematic case:

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

Here iter is actually not mutated, but copied. for i in &mut iter is required to mutate the iterator.

We could switch to linting against using an iterator variable after it was copied by a for loop, but there was no decision towards that.

5

由於Index是需要下列功能的性狀:

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

它消耗/移動用於索引(index)的值。在你的情況下,你試圖從一個借用結構中使用Range索引切片,但由於你只傳遞一個引用,並且該範圍沒有實現Copy,所以失敗。

您可以通過例如將test_slice的定義更改爲在索引中消耗StructWithRangeclone()s.range