Rust中for循环的确切定义是什么? [英] What is the exact definition of the for loop in Rust?
问题描述
我来自C(在较小程度上,C ++)背景。我写了以下代码片段:
I'm coming from a C (and to a lesser extent, C++) background. I wrote the following code snippet:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
编译并按预期运行,但后来我指定了传递给闭包的参数类型 print_me
因此:
This compiled and ran as expected, but then I specified the type of the argument passed to the closure print_me
thus:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
我收到了编译错误:
error[E0308]: mismatched types
--> src/main.rs:6:22
|
6 | print_me(k);
| ^
| |
| expected i32, found &{integer}
| help: consider dereferencing the borrow: `*k`
|
= note: expected type `i32`
found type `&{integer}`
现在这让我很困惑,直到我在中将
声明,工作正常: k
更改为& k
for
Now this confused me until I changed k
to &k
in the for
statement, which worked fine:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for &k in my_array.iter() {
print_me(k);
}
}
似乎我误解了 for
语法本身 - 或者可能是迭代器的确切工作方式 - 或者可能是指针的使用语法与指针相关[在C ++中相关但不同]。
It seems that I misunderstood the for
syntax itself -- or maybe the exact workings of an iterator -- or maybe the usage syntax of a reference vis-a-vis a pointer [which are related but distinct in C++].
在B的构造中为A {C1; C2; ...... Cn}
,究竟是 A
和 B
应该是什么?
In the construct for A in B { C1; C2; ... Cn }
, what exactly are A
and B
supposed to be?
推荐答案
首先,这里是参考中的定义
。
总而言之, B
是任何可以转换为实现的值的表达式Iterator< T>
trait,而 A
是无可辩驳的模式,它绑定类型的值T
。
To summarise, B
is any expression which evaluates to something that can be converted into a value that implements the Iterator<T>
trait, whilst A
is a irrefutable pattern that binds values of type T
.
在您的具体情况下, slice :: iter
返回 Iter< i32>
,实现 Iterator< Item =& i32>
。也就是说,它不会产生 i32
s,它会产生& i32
s。
In your specific case, slice::iter
returns an Iter<i32>
, which implements Iterator<Item = &i32>
. That is, it doesn't yield i32
s, it yields &i32
s.
因此,在第一个和第二个例子中, k
实际上绑定到& i32
s,而不是 i32
s。当您指定闭包的类型时,实际上是在指定错误的类型。最后一个例子的原因是因为 A
是一种模式,不是变量名。 c $ c> c> 实际做什么是解构& i32
,将 i32
部分绑定到名为 k
的变量。
Thus, in both the first and second examples, k
is actually binding to &i32
s, not i32
s. When you specified the type of the closure, you were actually specifying the wrong type. The reason the final example works is because A
is a pattern, not a variable name. What &k
is actually doing is "de-structuring" the &i32
, binding the i32
part to a variable named k
.
无可辩驳部分仅仅意味着模式必须始终工作。例如,你不能为某些东西中的某些(x)做,其中
thingy
实现迭代<方案< _>>
; 某些(x)
对于迭代器中的每个元素都不一定有效;因此,它是 refutable模式。
The "irrefutable" part simply means that the pattern must always work. For example, you can't do for Some(x) in thingy
where thingy
implements Iterator<Option<_>>
; Some(x)
would not necessarily be valid for every element in the iterator; thus, it's a refutable pattern.
这篇关于Rust中for循环的确切定义是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!