为什么`&`需要在迭代期间构造元组列表?

时间:2015-02-09 08:16:58

标签: rust

在迭代元组列表时,需要&才能使其正常工作。这样就行了......

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]

我确信它与我尚未完全内化的解构语法的复杂性有关。

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

1 个答案:

答案 0 :(得分:10)

这是因为iter method for an array [T]会返回iterator that yields &T values。这就是编译器说&#34; expected &-ptr, found tuple [E0271]&#34;。

的原因

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

这对于数组来说是一个问题,因为没有办法将单个元素移出数组;这样做会使整件事无效。

  

除了Vec和co。通过在unsafe块中实现其他逻辑来实现这一点。容器也可以提供into_iter,它为您提供一个迭代器,逐步使用容器,允许您移出值。

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

因此,您尝试对&(&str, f32, i32)进行解构,而不是(&str, f32, i32),因此需要额外&。 Rust不喜欢隐含性,所以你必须明确地去构造引用。这也有助于清楚地表明在这里发生了取消引用和副本