Iterator::findクロージャーに&&を渡さなければならない理由
https://stackoverflow.com/questions/43828013/why-is-being-used-in-closure-arguments
let a = [1, 2, 3]; assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); assert_eq!(a.iter().find(|&&x| x == 5), None);
回答
a
は[i32;3]
型[i32;3]
型はiter
メソッドが実装されていない[i32;3]
型は&[i32]
型にdereferenceする ★ 強制型&[i32]
型はiter
メソッドが実装しているiter
メソッドは、Iter<i32>
型を返すIter<i32>
型は、Iterator<Item=&32>
を実装している。Iterator<Item=&i32>
実装型Iterator::find<P>(&mut self, predicate: P) -> Option<Self::Item> where P: FnMut(&Self::Item) -> bool
Self::Item
は&i32
&Self::Item
となって綿割れるので&&i32
となる
- i32に戻すには2つのアプローチがある
- 明示的なdereferenceをする
a.iter().find(|x| **x == 2)
- ダブル参照を破壊するパターンマッチを使う
a.iter().find(|&&| x == 2)
- 明示的なdereferenceをする
パターンマッチによるデリファレンス
let double_ref = &&5; match double_ref { &&val => println!("{} + 3", val), }