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

Byr*_*ron 4 rust

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

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

但那不会......

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]
Run Code Online (Sandbox Code Playgroud)

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

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

DK.*_*DK. 10

这是因为iter数组[T]的方法返回一个产生&T值的迭代器.这就是编译器说" expected &-ptr, found tuple [E0271]" 的原因.

那为什么呢?嗯,一般来说,你不能复制T.除非代码假定更具限制性的边界,T: Copy否则T: Clone它只能移动类型的值T.

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

旁边:Vec和合作.通过在unsafe块中实现其他逻辑来使其工作来解决这个问题.容器也可以提供into_iter给你一个迭代器,逐步消耗容器,允许你移出值.

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

结果,你试图去构造一个&(&str, f32, i32),而不是一个(&str, f32, i32),因此是额外的&.Rust不喜欢隐含性,因此您必须明确地解构引用.这也有助于清楚地说明这里有一个解除引用和副本.

  • 他们被复制了.实际上,*一般来说*,如果是可复制的,则复制它们,如果不在引用后面则移动它们; 如果失败了,编译器会对你大喊大叫.如果你想要一个参考,你必须*询问*作为参考.这就是`ref`关键字的用途:`&(ref a,ref b,ref c)`.这在一个模式中说:"这个位置的东西?通过引用*将它绑定到一个名为`x`的变量".是的,你可以在模式有效的任何地方使用它:在匹配武器中,`if let`和常规`let`.娱乐时间! (4认同)
  • @Byron:哦!我差点忘了.你也可以(使用最近的`rustc`)删除对`.iter()`的显式调用.现在有一个[`IntoIterator`](http://doc.rust-lang.org/std/iter/trait.IntoIterator.html)特征,它从一个东西到它的迭代器.因为你正在迭代-ref,所以将`[...].iter()`更改为`&[...]`(或`&mut [...]`for`[...].iter_mut( )`).这也适用于带有`v`,`&v`和`&mut v`的向量`v`分别等同于`v.into_iter()`,`v.iter()`和`v.iter_mut()` . (3认同)