【问题标题】:Simplify if (x) Some(y) else None?简化 if (x) Some(y) else None?
【发布时间】:2019-11-01 10:11:11
【问题描述】:

这种常见的模式感觉有点冗长:

if (condition) 
  Some(result)
else None

我正在考虑使用函数来简化:

def on[A](cond: Boolean)(f: => A) = if (cond) Some(f) else None

这将最上面的例子简化为:

on (condition) { result }

这样的东西已经存在了吗?或者这是矫枉过正?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您可以先创建Option 并根据您的条件对其进行过滤:

    Option(result).filter(condition)
    

    或者如果conditionresult无关

    Option(result).filter(_ => condition)
    

    【讨论】:

    • 有趣!尽管我有点担心(a)条件/结果的意外(对我而言)顺序,以及(b)无论是否需要,总是计算result 的趋势。不过没想到!谢谢!
    • 计算结果有问题,猜猜你可以用Option(() => result).filter(_ => condition).map(_())修复它
    • 我不时使用它,但即使条件为假也需要评估结果感觉很奇怪...我喜欢 scalaz 方法,您可以在其中执行 condition.option(result) 并且我相信已评估懒惰,但这依赖于隐式,并且无论如何在我工作的地方都禁止使用scalaz……我希望这是标准scala的一部分。某种Option.cond(condition, result)
    【解决方案2】:

    Scalaz 包含option 函数:

    import scalaz.syntax.std.boolean._
    
    true.option("foo") // Some("foo")
    false.option("bar") // None
    

    【讨论】:

    • 我的功能让我担心的一件事是它没有明确表示正在创建一个选项。这既简单又克服了这个问题。谢谢!
    【解决方案3】:

    Scala 2.13 开始,Option 现在提供了 when 构建器,它就是这样做的:

    Option.when(condition)(result)
    

    例如:

    Option.when(true)(45)
    // Option[Int] = Some(45)
    Option.when(false)(45)
    // Option[Int] = None
    

    还要注意耦合的unless 方法,它的作用正好相反。

    【讨论】:

    • 现在 Scala 2.13 已经发布,这就是要走的路。
    【解决方案4】:

    您可以使用PartialFunction 伴随对象和condOpt

    PartialFunction.condOpt(condition) {case true => result}
    

    用法:

     scala> PartialFunction.condOpt(false) {case true => 42}
     res0: Option[Int] = None
    
     scala> PartialFunction.condOpt(true) {case true => 42}
     res1: Option[Int] = Some(42)
    

    【讨论】:

    • 这42个是什么意思? “真的”?本来可以避免建造地球... ;-) 以前没见过condOpt,谢谢!
    • 这绝对不是最有用的场景,但在许多其他情况下可能会有所帮助。
    • 这很漂亮!绝对喜欢这种方法。会在 Option 伴生对象而不是 PartialFunction 上寻找它,但这并不重要。 ?
    【解决方案5】:
    import scalaz._, Scalaz._
    val r = (1 == 2) ? Some(f) | None
    System.out.println("Res = " + r)
    

    【讨论】:

    • 啊,好用的三元运算符。谢谢!但我希望避免重复添加 Some() 和 None。
    【解决方案6】:

    这是另一种非常简单的方法:

    Option(condition).collect{ case true => result }
    

    一个简单的例子:

    scala> val enable = true
    enable: Boolean = true
    
    scala> Option(enable).collect{case true => "Yeah"}
    res0: Option[String] = Some(Yeah)
    
    scala> Option(!enable).collect{case true => "Yeah"}
    res1: Option[String] = None
    

    这里有一些将条件放入模式匹配的高级非布尔示例:

    val param = "beta"
    Option(param).collect{case "alpha" => "first"} // gives None
    
    Option(param).collect{case "alpha" => "first"
                          case "beta"  => "second"
                          case "gamma" => "third"} // gives Some(second)
    
    val number = 999
    Option(number).collect{case 0 => "zero"
                           case x if x > 10 => "too high"} // gives Some(too high)
    

    【讨论】:

      【解决方案7】:

      与 Scalaz 类似,Typelevel 猫生态系统具有 mouse packageoption

      scala> true.option("Its true!")
      res0: Option[String] = Some(Its true!)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-01
        • 1970-01-01
        • 2013-12-27
        • 1970-01-01
        • 1970-01-01
        • 2020-11-23
        • 2020-08-10
        • 1970-01-01
        相关资源
        最近更新 更多