为什么从负数开始的范围不会迭代?

时间:2015-09-05 15:22:40

标签: for-loop iterator rust

我刚开始学习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

这种行为的原因是什么?

1 个答案:

答案 0 :(得分: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],因为它更灵活,你什么都不会失去。