I would like a function which returns one of two iterators, both iterate over &u32:
fn values(&self) -> impl Iterator<Item = &u32> + '_
However, I get an error:
error[E0308]: `if` and `else` have incompatible types
--> src/main.rs:26:13
|
23 | / if self.use_table {
24 | | self.table.iter().map(|it| &it.value)
| | -------------------------------------
| | | |
| | | the expected closure
| | expected because of this
25 | | } else {
26 | | self.hash_table.values()
| | ^^^^^^^^^^^^^^^^^^^^^^^^ expected `Map<Iter<'_, KeyValue>, ...>`, found `Values<'_, usize, u32>`
27 | | }
| |_________- `if` and `else` have incompatible types
I tried boxing too, as suggested, but could not get it right.
Here is the full code:
use std::collections::HashMap;
struct KeyValue {
key: usize,
value: u32,
}
impl KeyValue {
fn new(key: usize, value: u32) -> Self {
Self { key, value }
}
}
struct Data {
table: Vec<KeyValue>,
hash_table: HashMap<usize, u32>,
use_table: bool,
}
impl Data {
// actual goal, as fn values is a trait itself
// both seem to have same return type
fn values(&self) -> impl Iterator<Item = &u32> + '_ {
if self.use_table {
self.table.iter().map(|it| &it.value)
} else {
self.hash_table.values()
}
}
// trying to box as help suggested
fn values_2(&self) -> Box<impl Iterator<Item = &u32> + '_>{
if self.use_table {
Box::new(self.table_values())
} else {
Box::new(self.hash_table_values())
}
}
// trying to return an iterator without reference and lifetime issues
fn values_no_ref(&self) -> impl Iterator<Item = u32> {
let x = self.table.iter().map(|&it| it.value);
let y = self.hash_table.values().map(|it| *it);
if self.use_table {
x
} else {
y
}
}
// same return type as above
fn table_values(&self) -> impl Iterator<Item = &u32> + '_ {
self.table.iter().map(|it| &it.value)
}
// same return type as above
fn hash_table_values(&self) -> impl Iterator<Item = &u32> + '_ {
self.hash_table.values()
}
}
fn main() {
let mut data = Data {
table: Vec::new(),
hash_table: HashMap::default(),
use_table: false,
};
data.table = vec![
KeyValue::new(1, 11),
KeyValue::new(2, 22),
KeyValue::new(3, 33),
];
data.hash_table.insert(4, 44);
data.hash_table.insert(5, 55);
data.hash_table.insert(6, 66);
for value in data.values() {
println!("value = {value}");
}
}