简体   繁体   中英

Why is this parameter dereferencing correctly in this Rust function?

New to Rust, and still stumbling a bit...I made the below function which works as expected.

If I have parameters such as n = 18 , factors = &[3, 6] , the function will check if any of the "factors" are a multiple of n.

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

But I'm trying to understand how the referencing and "dereferencing" of "y" in .filter(|&y| *y != 0) is working. My understanding is that "&y" is "referential address of y". So shouldn't you have to write it as filter(|&y| *(&y).= 0)... to get the correct "dereferencing" of y using the "*"?

&[T]::into_iter() gives an iterator with Item = &T . The closure passed to Iterator::filter takes an argument of type &Item . So in your case, the closure takes an argument of type &&u32 . In order to be able to compare this argument with 0, you need to get rid of the two levels of reference, which you can do either in the parameter definition, or when you use y . So your choices are:

  • |y| **y != 0 |y| **y != 0 dereference both levels on use,
  • |&y| *y != 0 |&y| *y != 0 dereference one level in the parameters and one on use,
  • |&&y| y != 0 |&&y| y != 0 dereference both levels in the parameters.

Moreover since u32 implements Copy , you can get rid of one level of indirection using Iterator::copied :

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

PS: You can check the type of y by adding a deliberately wrong type annotation and looking at the error messages:

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

Gives this error message:

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) -> _`

Giving the type of the closure argument as: &'r &u32

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM