For loop Rust中for循环的确切定义是什么?
我来自C(在较小程度上是C++)背景。我编写了以下代码片段:For loop Rust中for循环的确切定义是什么?,for-loop,reference,iterator,rust,For Loop,Reference,Iterator,Rust,我来自C(在较小程度上是C++)背景。我编写了以下代码片段: fn main() { let my_array = [1, 2, 3]; let print_me = |j| println!("= {}", j); for k in my_array.iter() { print_me(k); } } 这是按预期编译和运行的,但随后我指定了传递给闭包的参数类型print\u me,因此: fn main() { let my_array
fn main() {
let my_array = [1, 2, 3];
let print_me = |j| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
这是按预期编译和运行的,但随后我指定了传递给闭包的参数类型print\u me
,因此:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
我得到一个编译错误:
错误[E0308]:类型不匹配
-->src/main.rs:6:22
|
6 |打印(k);
| ^
| |
|应为i32,找到&{integer}
帮助:考虑取消借阅:'*k '
|
=注意:应为'i32'类型`
找到类型`&{integer}`
现在这让我很困惑,直到我在for
语句中将k
改为&k
,效果很好:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for &k in my_array.iter() {
print_me(k);
}
}
似乎我误解了语法本身,或者可能是迭代器的确切工作方式,或者可能是引用相对于指针的用法语法[在C++中是相关但不同的]
在B{C1;C2;…Cn}
中A的构造中,A
和B
到底应该是什么?首先,这里是到的链接
总之,B
是任何表达式,其计算结果可以转换为实现迭代器
特性的值,而a
是一种无可辩驳的模式,它绑定了T
类型的值
在您的特定情况下,返回一个。也就是说,它不会产生i32
s,而是产生&i32
s
因此,在第一和第二示例中,k
实际上绑定到&i32
s,而不是i32
s。指定闭包的类型时,实际上指定了错误的类型。最后一个示例之所以有效,是因为A
是一种模式,而不是变量名。&k
实际上所做的是对&i32
进行“去结构化”,将i32
部分绑定到名为k
的变量
“无可辩驳”部分仅仅意味着模式必须始终有效。例如,您不能对thingy中的某些(x)执行,其中thingy
实现了Iterator
Some(x)
不一定对迭代器中的每个元素都有效;因此,这是一个可反驳的模式。许多迭代器实际上返回一个引用而不是一个值。当然,您必须检查.iter()
的返回类型,它应该是迭代器的形式:X
将是返回的变量的类型
因此,这里:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
该X
是&i32
(对i32
的引用),因此k
具有类型&i32
这就是为什么在调用print\u me
时出现错误:&i32
在预期的i32
位置传递
这里有多个可能的修复:
指定要打印的不同类型:
let print_me = |j: &i32| println!("= {}", j);
取消引用k的值
:
print_me(*k);
通过在循环中分解结构来更改k
的类型:
for &k in my_array.iter() { ... }
由于..的。。in
接受一个无可辩驳的模式,因此可以像在match
表达式中一样进行模式匹配,但变量的类型必须匹配(否则会出现编译器时间错误)
为了更好地说明这一点,我们可以使用稍微复杂一点的示例:
fn main() {
let my_array = [(1, 2), (2, 3), (3, 4)];
let print_me = |a: i32, b: i32| println!("= {} {}", a, b);
for &(j, k) in my_array.iter() {
print_me(j, k)
}
}
my_数组的类型是[(i32,i32)]
:一个2的元组数组i32
。因此,.iter()
的结果属于类型迭代器
:对2的元组引用的迭代器i32
aka&(i32,i32)
当我们使用无可辩驳的模式&(j,k)
时,我们会对元组进行分解,以便:
- 第一个元素绑定到
j
(推断为i32
类型,仅因为i32
是Copy
)
- 第二个元素绑定到
k
((推断为类型i32
)
j
和k
因此成为该元素内i32
的临时副本