つまずいた場所
let vec: Vec<String> = vec![
"hoge".to_string(),
"fuga".to_string(),
"piyopiyo".to_string(),
];
// 要素がコピーされた Vec が出来る
let filtered_vec: Vec<String> =
vec.iter().filter(|s| s.len() <= 5).cloned().collect();
let mut map: HashMap<i32, String> = HashMap::new();
map.insert(0, "hoge".to_string());
map.insert(1, "fuga".to_string());
map.insert(2, "piyopiyo".to_string());
// error[E0271]: type mismatch resolving ...
let filtered_map: HashMap<i32, String> =
map.iter().filter(|(_k, v)| v.len() <= 5).cloned().collect();
ナンデ?
理由
まず cloned
は Iterator<Item=&T>
を Iterator<Item=T>
に変換するもの。
つまり参照を受けて値に変換する。
しかし HashMap::iter
は Iterator<Item=(&Key, &Value)>
を返す。
この時、 (&Key, &Value)
は参照を格納した値であって、それ自体は参照ではない。
解決法
前述の理由により、無理やり
.map(|pair| pair.clone())
としてもシャローコピーされるだけで上手くいかない。
.map(|(k, v)| (k.clone(), v.clone()))
とする必要がある。
今回は i32
が Copy
なので、
.map(|(&k, v)| (k, v.clone()))
でも可。
短くかける方法があれば教えてください。