为什么在迭代期间需要“&”来解构元组列表?

Why is `&` needed to destructure a list of tuples during iteration?

迭代元组列表时,需要 & 才能使其工作。因此这将起作用...

for &(a, b, c) in [("hello", 1.0, 5), ("world", 2.0, 2)].iter() {
    println!("{} {} {}", a, b, c);
}

但这不会...

for (a, b, c) in [("hello", 1.0, 5), ("world", 2.0, 2)].iter() {
    println!("{} {} {}", a, b, c);
}

// type mismatch resolving `<core::slice::Iter<'_, (&str, _, _)> as core::iter::Iterator>::Item == (_, _, _)`:
// expected &-ptr,
found tuple [E0271]

我确信这与我尚未完全理解的解构语法的复杂性有关。

你能解释一下 & 符号背后的句法真相吗?

因为iter method for an array [T] returns an iterator that yields &T values。这就是编译器说“expected &-ptr, found tuple [E0271]”的原因。

那是为什么呢?好吧,一般,你不能复制T。除非代码假定 T: CopyT: Clone 的限制更严格,否则它只能 移动 类型 T 的值。

这是数组的一个问题,因为无法将单个元素移出数组;这样做会使整个事情无效。

Aside: Vec and co. get around this by implementing additional logic in unsafe blocks to make it work. Containers may also provide into_iter which gives you an iterator that incrementally consumes the container, allowing you to move values out.

因为您希望数组 iter 方法适用于 所有 数组,所以它会依次生成对每个元素的不可变引用。

因此,您试图解构 &(&str, f32, i32),而不是 (&str, f32, i32),因此需要额外的 &。 Rust 不喜欢隐式,所以你必须 明确地 解构引用。这也有助于明确这里发生了取消引用 和复制