Rust中for循环的确切定义是什么? [英] What is the exact definition of the for loop in Rust?

查看:963
本文介绍了Rust中for循环的确切定义是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来自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 i32s, it yields &i32s.

因此,在第一个和第二个例子中, k 实际上绑定到& i32 s,而不是 i32 s。当您指定闭包的类型时,实际上是在指定错误的类型。最后一个例子的原因是因为 A 是一种模式,不是变量名 c c> 实际做什么是解构& i32 ,将 i32 部分绑定到名为 k 的变量。

Thus, in both the first and second examples, k is actually binding to &i32s, not i32s. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆