У меня есть перечисление с вариантами со значением:

enum Foobar {
    Foo,
    Bar(T),
    Baz(G),
}

У меня есть кусок кода, где мне нужно сопоставить значение перечисления, но я не хочу его уничтожать.

fn foobar(value: Foobar, f1: F1, f2: F2) -> bool
где
    F1: Fn(T) -> bool,
    F2: Fn(G),
{
    let res = match value {
        Foobar::Foo => true,
        Foobar::Bar(v) => f1(v),
        Foobar::Baz => false,
    };
    if let Foobar::Baz(v2) = value {
        f2(v2);
    }
    res
}

Это не компилируется, потому что ожидается unit struct, unit variant или constant, найден tuple variant Foobar::Baz

.

Я не хочу приводить его к Foobar::Baz(_), потому что это заставит Copy trait на G, а я этого не хочу.

Мой пример немного искусственный, но предположим, что мне нужно сохранить отдельный вызов f2.

Есть ли способ подобрать вариант перечисления, не разрушая его?

Ответы (1)

Вы не можете.

Но это все равно не поможет. Проблема в том, что value недоступно после match, потому что вы (возможно) переместили данные из него в f1.

Вы можете исправить это, немного реорганизовав код так, чтобы вы смотрели на Baz только тогда, когда значение из Bar не было перемещено:

fn foobar(value: Foobar, f1: F1, f2: F2) -> bool
где
    F1: Fn(T) -> bool,
    F2: Fn(G),
{
    let res = match value {
        Foobar::Foo => true,
        Foobar::Bar(v) => f1(v),
        Foobar::Baz(v2) => {
            f2(v2);
            false
        },
    };
    res
}

2022 WebDevInsider