Код с деструктурированием Enum, помогите исправить
Исправить код чтобы в качестве верного результата печатался индекс вектора с номером "3". Сейчас код выдает два результата "1" и "3": запустить код онлайн
Подробнее о том какие критерии:
- Переменная
find_meимеет значениеSource::Base, при итерациях вектораVecдолжны бать отсеяны любые варианты сSource::Currкак не подходящие. - Найденный индекс в векторе должен быть с
word_2. - Проверка соответствий по значению
i32не требуется.
Другими словами, нужно исправить match (или заменить его на что-то другое, если есть такая замена), что выдаст индекс "3" вектора в качестве единственного верного результата по той причине, что только этот индекс совпадает с find_me по таким критериям как Source::Baseи word_2.
pub enum Source {
Curr(&'static str, i32),
Base(&'static str, i32),
}
pub struct Data {
field: Source,
}
fn main() {
#[rustfmt::skip]
let vec = vec![
Data{field: Source::Curr("word", 1)},
Data{field: Source::Curr("word_2", 2)},
Data{field: Source::Base("word", 3)},
Data{field: Source::Base("word_2", 4)},
];
let find_me = Source::Base("word_2", 2);
foo(find_me, vec);
}
fn foo(find_me: Source, vec: Vec<Data>) {
let (name, _) = match find_me {
Source::Base(x, y) => (x, y),
Source::Curr(x, y) => (x, y),
};
let mut index = 0;
for item in vec.into_iter() {
match item {
Data {
field: Source::Curr(txt, _),
} if name == txt => println!("{}", index),
Data {
field: Source::Base(txt, _),
} if name == txt => println!("{}", index),
_ => (),
}
index += 1;
}
}
Ответы (1 шт):
Автор решения: Ziaft
→ Ссылка
Думаю, вам следует написать следующую функцию:
fn variant_eq<T>(first: &T, second: &T) -> bool {
std::mem::discriminant(first) == std::mem::discriminant(second)
}
Или вот такую:
fn variant_eq(a: &Source, b: &Source) -> bool {
match (a, b) {
(&Source::Base(..), &Source::Base(..)) => true,
(&Source::Curr(..), &Source::Curr(..)) => true,
_ => false,
}
}
И использовать ее при сравнении:
match item {
Data {
field: Source::Curr(txt, _),
} if name == txt && variant_eq(&item.field, &find_me) => {
println!("{}", index)
}
Data {
field: Source::Base(txt, _),
} if name == txt && variant_eq(&item.field, &find_me) => {
println!("{}", index)
}
_ => (),
}
Первая, конечно, предпочтительней, так как она шаблонна, но вторая нагляднее, поэтому решил привести и ее.