Aks*_*aik 0 iterator reference rust
我在 Rust 书中遇到了下面的例子。
for &item in list.iter() {
if item > largest {
largest = item;
}
}
Run Code Online (Sandbox Code Playgroud)
我想这意味着list.iter()返回对列表中元素的引用,&item但是在将其与最大数字进行比较时,为什么我们不使用*item?&item另外,当我将第一行中的to更改为时,编译器item强制我在第二行和第三行中使用。*item
我在网上看到了另一个例子。
(0..).map(|x| x * x)
.take_while(|&x| x <= limit)
.filter(|x| is_even(*x))
Run Code Online (Sandbox Code Playgroud)
这里的闭包take_while接受&x但直接使用x,但闭包filter接受x而不引用但传递*x给is_even。
那么这在 Rust 中是如何工作的呢?
您在这里看到的称为解构。通过此功能,您可以使用图案来分解结构。
您可能已经看到过类似的内容let (a, b) = returns_a_tuple();。这里,元组被解构。您还可以解构引用:
// The comments at the end of the line tell you the type of the variable
let i = 3; // : i32
let ref_i = &i; // : &i32
let ref_ref_i = &ref_i; // : &&i32
let &x = ref_i; // : i32
let &y = ref_ref_i; // : &i32
let &&z = ref_ref_i; // : i32
// All of these error because we try to destructure more layers of references
// than there are.
let &a = i;
let &&b = ref_i;
let &&&c = ref_ref_i;
Run Code Online (Sandbox Code Playgroud)
这具有反直觉的效果,即在模式中添加的越多,变量的类型就越&&少。但它在解构的上下文中确实有意义:当您已经在模式中提到结构时,该结构将不再位于绑定变量中。
(值得注意的是,这种“解构引用”仅适用于 的裁判类型Copy。否则您将收到“无法移出借用的内容”错误。)
for现在这与你的循环和闭包有什么关系?事实证明:模式无处不在。forfor 循环中和之间的槽in是一种模式,函数和闭包的参数也是模式!这有效:
// Destructuring a tuple in the for loop pattern
let v = vec![3];
for (i, elem) in v.iter().enumerate() {}
// Destructuring an array in the function argument (works the same for closures)
fn foo([x, y, z]: [f32; 3]) {}
Run Code Online (Sandbox Code Playgroud)
我想这意味着
list.iter()返回对列表中元素的引用
确切地。
... 因此
&item
“因此”在这里不正确。此代码的作者不想使用对该项目的引用,而是使用实际值。因此他们&在模式中添加了 来解构引用。
但在与最大数字进行比较时,为什么我们不使用
*item?
是的,因为引用已经被解构模式删除了。
&item另外,当我将第一行中的to更改为时,编译器item强制我在第二行和第三行中使用。*item
是的,因为现在模式不再破坏引用,所以item再次引用。这是所有这一切的基本要点:大多数时候,您可以通过添加 a 来删除模式中的引用& ,也可以在使用变量时通过添加 a 来删除引用*。
这里的闭包
take_while接受&x但直接使用x,但闭包filter接受x而不引用但传递*x给is_even。
现在应该很清楚为什么会这样了吧?闭take_while包通过模式中的解构来删除引用,而filter闭包则通过标准解引用来删除引用。
您可以在本书的这一章中阅读有关所有这些内容的更多信息。
| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |