【问题标题】:Why is this parameter dereferencing correctly in this Rust function?为什么这个参数在这个 Rust 函数中正确解引用?
【发布时间】:2020-04-28 14:28:41
【问题描述】:

Rust 新手,但仍然有点磕磕绊绊......我制作了下面的函数,它按预期工作。

如果我有n = 18factors = &[3, 6]等参数,该函数将检查是否有任何“因子”是n的倍数。

fn check_multiple(n: u32, factors: &[u32]) -> bool {
  factors.into_iter().filter(|&y| *y != 0).any(|z| n % z == 0)
}

但我试图了解.filter(|&y| *y != 0) 中“y”的引用和“解除引用”是如何工作的。我的理解是“&y”是“y的引用地址”。所以你不应该把它写成filter(|&y| *(&y) != 0)... 来使用“*”获得正确的“取消引用”吗?

【问题讨论】:

  • "我的理解是 "&y" 是 y 的引用地址",是的,你是对的,现在y 包含对 y 值的引用。要获取 y 的值,您可以取消引用 (*y),以便您可以对“y”进行比较
  • 我一般不会在切片上使用into_iter()。只是 iter() 做同样的事情并且更常见,所以我会坚持使用它以保持一致性并避免混淆。
  • 感谢斯文的提示!

标签: rust


【解决方案1】:

&[T]::into_iter() 给出了一个带有Item = &T 的迭代器。传递给Iterator::filter 的闭包接受&Item 类型的参数。因此,在您的情况下,闭包采用&&u32 类型的参数。为了能够将此参数与 0 进行比较,您需要摆脱两个级别的引用,您可以在参数定义中或在使用 y 时这样做。所以你的选择是:

  • |y| **y != 0 在使用时取消引用两个级别,
  • |&y| *y != 0 在参数中取消引用一级,在使用中取消引用,
  • |&&y| y != 0 取消引用参数中的两个级别。

此外,由于u32 实现了Copy,您可以使用Iterator::copied 摆脱一级间接:

factors.into_iter().copied().filter (|&y| y != 0)

PS:您可以通过添加故意错误的类型注释并查看错误消息来检查y的类型:

fn check_multiple(n: u32, factors: &[u32]) -> bool {
   factors.into_iter().filter (|y: ()| y != 0).any (|z| n % z == 0)
}

给出这个错误信息:

error[E0631]: type mismatch in closure arguments
 --> src/lib.rs:2:23
  |
2 |   factors.into_iter().filter (|y: ()| y != 0).any(|z| n % z == 0)
  |                       ^^^^^^  -------------- found signature of `fn(()) -> _`
  |                       |
  |                       expected signature of `for<'r> fn(&'r &u32) -> _`

给出闭包参数的类型为:&amp;'r &amp;u32

【讨论】:

    猜你喜欢
    • 2019-06-28
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2012-06-11
    • 2017-10-05
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多