我刚刚开始学习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
这种行为的原因是什么?
类型推断导致您范围内的两个数字均为,usize
不能代表负数。因此,范围是从usize::MAX
到n
,从没有任何成员。
为了找出答案,我使用了一个技巧来打印出事物的类型:
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);
}
}
额外的好消息是,这种烦恼已在最新版本的Rust中得到了解决。它将导致警告,最终导致错误:
warning: unary negation of unsigned integers will be feature gated in the future
for i in -1 .. n {
^~
还要注意,您永远不要接受a&Vec<T>
作为参数。始终使用a,&[T]
因为它更灵活,而且您一无所获。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句