【问题标题】:Scala: Try .getOrElse vs if/elseScala:尝试 .getOrElse 与 if/else
【发布时间】:2016-03-21 02:20:07
【问题描述】:

我是一个相当新的 Scala 开发人员。我是一位经验丰富的 Java 开发人员,到目前为止,我一直很喜欢 Scala 的简单性。我真的很喜欢函数式结构,而且它们经常迫使你编写更简洁的代码。但是最近我注意到,由于舒适和简单,我最终使用了在 Java 中不一定会使用的结构,实际上会被认为是一种不好的做法,例如

private def convertStringToSourceIds(value: String) : Seq[Integer] = {
    Try(value.split(",").toSeq.map(convertToSourceId(_))).getOrElse(Seq())
}

同样的代码sn-p可以写成

private def convertStringToSourceIds(value: String) : Seq[Integer] = {
    if(value!=null) value.split(",").toSeq.map(convertToSourceId(_)) else Seq()
}

我的一部分意识到Try/getOrElse 块的设计考虑了Options,但它通常使代码更具可读性并处理您可能错过的情况(当然这并不总是一件好事)。

我很想知道有经验的 Scala 开发人员对此有何看法。

【问题讨论】:

    标签: scala


    【解决方案1】:

    我没有声称任何“经验”头衔,但出于几个原因,我更喜欢你的第二个构造

    • 抛出异常(在这种情况下为 NPE)代价高昂,最好避免;它应该保持不变,例外al

    • if 是 Scala 中的表达式,它避免了声明“悬空”变量来保存测试结果(就像三元运算符一样)。或者,match..case 构造提供了非常易读的代码。

    • 我会亲自返回一个Option[Seq[Integer]] 以“回传”valuesnull 的信息,并有助于进一步链接您的函数。

    类似

    private def convertStringToSourceIds(value: String) : Option[Seq[Integer]] = value match {
        case null => None
        case _ => Some(value.split(",").map(convertToSourceId(_)))
    }
    

    注意 1:不确定您是否需要 toSeq

    注 2:无论好坏,看起来都有点 Haskellish

    Scala + FP 的组合几乎可以加倍肯定你会得到不同的意见:)

    编辑 请阅读下面的 cmets 以了解其他原因和替代方案,即

    def convertStringToSourceIds(value: String): Option[Array[String]] = Option(value).map(_.split(",").map(convertToSourceId(_)))
    

    【讨论】:

    • 不需要匹配,因为Option会自动匹配,只需要Option(value).map(convertToSourceId(_.split(",")))即可。
    • 非常感谢,有道理。在 Scala 中,您有几种方法可以正确地做某事,这可能会让人感到困惑。
    • Throwing an exception (an NPE in this case) is expensive and best avoided。我会强调使用异常时失去参照透明度的重要性(通过programmers.stackexchange.com/questions/223329/…),而不是性能影响(我从您对expensive的使用中解释了这一点.
    • @KevinMeredith 对,最好避免使用它,因为它的潜在副作用和处理程序控制流的不良机制。它也可能很慢:stackoverflow.com/questions/299068/how-slow-are-java-exceptions
    【解决方案2】:

    如果可以,请使用Options 而不是null 来显示缺失值的时间。

    假设你不能使用Options,一个更易读的处理方法可能是

    private def convertStringToSourceIds(value: String) : Seq[Integer] = value match {
        case null => Seq();
        case s => s.split(",").toSeq.map(convertToSourceId(_));
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      相关资源
      最近更新 更多