for-loop - Rust 中 for 循环的确切定义是什么?

标签 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_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);
    }
}

编译错误:

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}`

现在这让我感到困惑,直到我在 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);
    }
}

我似乎误解了 for 语法本身——或者可能是迭代器的确切工作原理——或者可能是引用相对于指针的使用语法 [这是相关的但在 C++ 中是不同的]。

在构造 for A in B { C1; C2; ... Cn AB 到底应该是什么?

最佳答案

首先,这里有一个链接 the definition of for in the reference .

总结一下,B是任何表达式,其计算结果可以转换为实现 Iterator<T> 的值特征,同时 A是一个无可辩驳的模式,它绑定(bind)了 T 类型的值。 .

在您的具体情况下, slice::iter 返回 Iter<i32> ,这implements Iterator<Item = &i32> .也就是说,它不会产生 i32 s, 它产生 &i32

因此,在第一个和第二个示例中,k实际上绑定(bind)到 &i32 s,不是 i32秒。当您指定闭包的类型时,您实际上是在指定错误的类型。最后一个例子起作用的原因是因为 A是一个模式,不是变量名。什么&k 实际上正在“解构”&i32 , 绑定(bind) i32部分到名为 k 的变量.

“无可辩驳”部分只是意味着该模式必须始终 有效。例如,你不能做 for Some(x) in thingy其中 thingy工具 Iterator<Option<_>> ; Some(x)不一定对迭代器中的每个元素都有效;因此,这是一个可反驳的模式

关于for-loop - Rust 中 for 循环的确切定义是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27224927/

相关文章:

c++ - 使用指针写入标准容器

python - 如何比较元组(int)的元素以确定它是否存在于列表中

c++ - 无限for循环?

C++ 通过引用传递

macos - 是否可以在文件系统上创建 "weakly referenced"硬链接(hard link)?

memory-management - Lua - 数一数。对表的引用

c# - 使用循环在 C# 中创建数字及其平方的列表

Python帮助使用for循环来改变x

c++ - 如何引用其他类的函数来为 vector 添加值

rust - 从函数中有效地返回 1-9 个字节