it-swarm-ja.com

一致式を使用してオブジェクトを移動できますか?

Rust 1.15.1を使用していますが、最近、簡単な解決策を見つけることができない問題に遭遇しました。

パターンマッチングを使用した例を見ると、通常、一致式のオブジェクトが分解され、そのオブジェクト内のメンバーで引き続き機能します。ただし、それを非構造化するのではなく、それと照合して、プロパティに応じて他のいくつかの関数の1つにオブジェクト全体を(移動セマンティクスを使用して)ディスパッチするだけです。

次のコードは機能し、私が必要とするものを正確に実行します。ただし、「人工」列挙型と2番目の一致式を導入する必要があります。もっと簡単で簡単な解決策があるのだろうか?

#[derive(Debug)]
enum Number {
    Constant { value: i32 },
}

fn process_even(n: Number) {
    println!("even: {:?}", n);
}

fn process_odd(n: Number) {
    println!("odd: {:?}", n);
}

fn process(n: Number) {
    enum Action {
        ProcessEven,
        ProcessOdd,
    }

    let action = match n {
        Number::Constant { value: c, .. } if 0 == c % 2 => Action::ProcessEven,
        _ => Action::ProcessOdd,
    };

    match action {
        Action::ProcessEven => process_even(n),
        Action::ProcessOdd => process_odd(n),
    }
}

fn main() {
    process(Number::Constant { value: 4711 });
    process(Number::Constant { value: 2000 });
}
3
Jonny Dee

試してみましたかsingn

fn process(n: Number) {
    match n {
        Number::Constant { value: c, .. } if c % 2 == 0 => process_even(n),
        _ => process_odd(n)
    }
}

これは、valuei32、つまりCopyであるために機能します。つまり、コンパイラーは、移動したり借用したりすることなく、コピーすることができます。それよりも複雑なタイプを扱っている場合は、第2段階を回避できない可能性があります。

とはいえ、thatの場合でも、オプションが2つしかない場合は、trueまたはfalseを返すことができます。 Or最初の一致からprocess_even/process_oddを関数ポインタとして直接返し、それを呼び出すことができます。

fn process(n: Number) {
    let action = match n {
        Number::Constant { value: c, .. } if c % 2 == 0 => process_even as fn(_),
        _ => process_odd
    };

    action(n)
}
2
DK.