在迭代元组列表时,需要&
才能使其正常工作。这样就行了......
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]
我确信它与我尚未完全内化的解构语法的复杂性有关。
你能解释一下&符背后的句法真相吗?
答案 0 :(得分:10)
这是因为iter
method for an array [T]
会返回iterator that yields &T
values。这就是编译器说&#34; expected &-ptr, found tuple [E0271]
&#34;。
那为什么呢?好吧,一般,你不能复制T
。除非代码假定T: Copy
或T: Clone
的限制更严格,否则它只能移动类型为T
的值。
这对于数组来说是一个问题,因为没有办法将单个元素移出数组;这样做会使整件事无效。
除了:
Vec
和co。通过在unsafe
块中实现其他逻辑来实现这一点。容器也可以提供into_iter
,它为您提供一个迭代器,逐步使用容器,允许您移出值。
因为您希望数组iter
方法适用于所有数组,所以它会依次产生对每个元素的不可变引用。
因此,您尝试对&(&str, f32, i32)
进行解构,而不是(&str, f32, i32)
,因此需要额外&
。 Rust不喜欢隐含性,所以你必须明确地去构造引用。这也有助于清楚地表明在这里发生了取消引用和副本。