Biorąc pod uwagę to definicja foo
:Warunkowo powrócić pusty iterator z flat_map
let foo = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
Chciałbym móc napisać kod tak:
let result: Vec<_> = foo.iter()
.enumerate()
.flat_map(|(i, row)| if i % 2 == 0 {
row.iter().map(|x| x * 2)
} else {
std::iter::empty()
})
.collect();
ale zgłasza błąd o if a także klauzule o niekompatybilnych typach. Próbowałem usunięcie map
czasowo i próbowałem definiowanie pusty wektor zewnątrz zamknięcia i powrót iterator nad tym tak:
let empty = vec![];
let result: Vec<_> = foo.iter()
.enumerate()
.flat_map(|(i, row)| if i % 2 == 0 {
row.iter() //.map(|x| x * 2)
} else {
empty.iter()
})
.collect();
To wydaje trochę głupie ale kompiluje. Jeśli spróbuję odkomentować kod map
, to nadal narzeka on na klauzule if i else mające niezgodne typy. Oto część z komunikatem o błędzie:
error[E0308]: if and else have incompatible types
--> src/main.rs:6:30
|
6 | .flat_map(|(i, row)| if i % 2 == 0 {
| ______________________________^
7 | | row.iter().map(|x| x * 2)
8 | | } else {
9 | | std::iter::empty()
10 | | })
| |_________^ expected struct `std::iter::Map`, found struct `std::iter::Empty`
|
= note: expected type `std::iter::Map<std::slice::Iter<'_, {integer}>, [[email protected]/main.rs:7:28: 7:37]>`
found type `std::iter::Empty<_>`
Wiem, że mógłbym napisać coś, że robi to, co chcę z kilku zagnieżdżonych for
pętli, ale chciałbym wiedzieć, czy istnieje lakoniczny sposób, żeby to napisać za pomocą iteratorów.
"*' | _ | jeśli i% 2 == 0 {true} else {false} '*" Proszę, po prostu '| _ | i% 2 == 0' ...; -] – ildjarn
@ildjarn hah, tak. Podniosłem również modulo z zamknięcia. chociaż i tak kompilator może ją zoptymalizować. – the8472