【问题标题】:Can I use '<' and '>' in match?我可以在比赛中使用 \'<\' 和 \'>\' 吗?
【发布时间】:2017-12-17 21:27:56
【问题描述】:

我正在尝试做一个简单的二次函数,该函数将通过枚举返回根数及其值:

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

【问题讨论】:

  • 惯用的 Rust 使用 snake_case 作为标识符。 solve_quadratic不是solveQuadratic
  • @Shepmaster 好点。幸运的是,在我能够编译它之后,Visual Studio Code 的 rls 插件也为我标记了它。 :)
  • 我想您最终会用计算值替换 0.01.0。请注意,当返回 QuadraticResult::TwoRoots(x, y) 时,不要假设 x != y。即使d 大于 0,-b + d.sqrt()-b - d.sqrt() 也可能相同。 Here's an easy example,但有限根也可能发生。您可能想要返回 Option&lt;(x1, x2)&gt; 并让调用者决定 x1x2 是否“足够接近”以被视为单根。

标签: rust match quadratic


【解决方案1】:

您可以使用 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),
}

【讨论】:

  • 只是想补充一点,在这种情况下,我绝对更喜欢“匹配”而不是“if/else”语句,因为恕我直言,代码看起来更整洁、更易读。
  • 我想到了另一件事。 “if/else”和“match”之间是否存在明显的性能差异?
  • @dawid 即使您在性能上会有任何差异 - 也不能保证在下一个版本中保持不变。如果您不被迫这样做,那么您不应该为这个级别的性能而烦恼。首先是可读性——优化是编译器的工作。 Here you can check assemble code of match and if
【解决方案2】:

如果你想处理某些值大于、等于或小于另一个值的三种情况,你可以匹配Ordering,你可以通过调用cmp(来自Ord特征)或@ 987654323@(来自PartialOrd 特征)。

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),
    }
}

【讨论】:

    【解决方案3】:

    You can,但您需要在执行此操作时创建一个变量绑定并将其转换为实际表达式:

    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 语句更好。

    【讨论】:

    • 谢谢西蒙。我将不得不接受雅各布的回答,因为他是第一个:)
    • 哦,完全没问题。我没有看到 Jacobs 的回答……哈,他们也几乎一模一样!我也可以删除我的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 2017-09-18
    • 2012-07-12
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多