2015-09-05 29 views
4

我剛剛開始學習Rust。在我用這種語言的第一步,我發現了一個奇怪的現象,當在下面的例子中main或其他功能進行迭代:爲什麼從負數開始的範圍不會迭代?

fn myfunc(x: &Vec<f64>) { 
    let n = x.len(); 
    println!(" n: {:?}", n); 
    for i in -1 .. n { 
     println!(" i: {}", i); 
    } 
} 

fn main() { 
    for j in -1 .. 6 { 
     println!("j: {}", j); 
    } 

    let field = vec![1.; 6]; 
    myfunc(&field); 
} 

雖然main循環正常顯示,沒有打印的裏面myfunc循環,我得到以下輸出:

j: -1 
j: 0 
j: 1 
j: 2 
j: 3 
j: 4 
j: 5 
    n: 6 

什麼是這種行爲的原因是什麼?

回答

7

類型推斷導致您範圍內的兩個數字都是usize,這不能代表負數。因此,範圍從usize::MAXn,它從來沒有任何成員。

要了解這一點,我用了一招,打印出的類型的東西:

let() = -1 .. x.len(); 

其中有此錯誤:

error: mismatched types: 
expected `core::ops::Range<usize>`, 
    found `()` 
(expected struct `core::ops::Range`, 
    found()) [E0308] 
let() = -1 .. x.len(); 
    ^~ 

潛入細節,slice::len返回usize。你的-1是一個無類型的整數值,它將符合它適合的任何上下文(如果它沒有任何符合,它將回落到i32)。

在這種情況下,就好像您實際輸入了(-1 as usize)..x.len()

好消息是,你可能不想從-1開始。切片是零索引:

fn myfunc(x: &[f64]) { 
    let n = x.len(); 
    println!(" n: {:?}", n); 
    for i in 0..n { 
     println!(" i: {}", i); 
    } 
} 

額外的好消息的是,這個煩惱是fixed in the newest versions of Rust。這將導致一個警告,然後最終的錯誤:

warning: unary negation of unsigned integers will be feature gated in the future 
    for i in -1 .. n { 
       ^~ 

另外請注意,你不應該接受&Vec<T>作爲參數。始終使用&[T],因爲它更靈活,並且不會丟失任何東西。

+2

這是令人驚訝的行爲。我希望'rustc'至少會發出一個警告,即負值被「包裹」。 –

+0

@MatthieuM。哦,謝謝你提醒我!它實際上*是*固定的,看我的更新。^_^ – Shepmaster

+0

啊!談好時機! –