web-dev-qa-db-ja.com

「<」と「>」を組み合わせて使用​​できますか?

私は列挙型を介して根の数とそれらの値を返す単純な二次関数を実行しようとしています:

enum QuadraticResult {
    None,
    OneRoot(f32),
    TwoRoots(f32, f32),
}

fn solveQuadratic(a: f32, b: f32, c: f32) -> QuadraticResult {
    let delta = b * b - 4.0 * a * c;
    match delta {
        < 0 => return QuadraticResult::None,
        > 0 => return QuadraticResult::TwoRoots(0.0, 1.0),
        _ => return QuadraticResult::OneRoot(0.0),
    }
}

「<」と「>」について文句を言うので、これはコンパイルされません。 matchでこれを達成する方法はありますか、またはifを使用する必要がありますか

11
dawid

match guard を使用できますが、単純なifステートメントよりも冗長に感じられます。

return match delta {
    d if d < 0 => QuadraticResult::None,
    d if d > 0 => QuadraticResult::TwoRoots(0.0, 1.0),
    _   => QuadraticResult::OneRoot(0.0),
}
12
Jacob Krall

ある値が別の値より大きい、等しい、または小さい3つのケースを処理する場合は、Orderingを照合できます。これは、 cmp を呼び出すことで取得できます Ord trait)または partial_cmpPartialOrd 特性から).

fn solve_quadratic(a: f32, b: f32, c: f32) -> QuadraticResult {
    let delta = b * b - 4.0 * a * c;
    match delta.partial_cmp(&0.0).expect("I don't like NaNs") {
        Ordering::Less => QuadraticResult::None,
        Ordering::Greater => QuadraticResult::TwoRoots(0.0, 1.0),
        Ordering::Equal => QuadraticResult::OneRoot(0.0),
    }
}
9
Francis Gagné

できます ですが、変数バインディングを作成して実際の式に変換する必要があります。

match delta {
    d if d < 0.0 => QuadraticResult::None,
    d if d > 0.0 => QuadraticResult::TwoRoots(0.0, 1.0),
    _ => QuadraticResult::OneRoot(0.0),
}

ただし、これをifステートメントに分割するよりも良いとは思いません。

4
Simon Whitehead