【问题标题】:scala Option and datatypesscala 选项和数据类型
【发布时间】:2021-08-31 13:50:09
【问题描述】:

我在尝试 getOrElse 2 个值时遇到错误。作为一个精简的例子,我要做的就是:

  • 取一个字符串值
  • 检查它是否是一个范围(例如50-60)。如果是,则取“-”之前的第一个值,否则取整个值
  • 将值作为 Option[Double] 返回以进行进一步处理
def deriveResult(inputValue: Option[String]): String = {
    val hyphenIndex = inputValue.get.indexOf("-")
    // parse the low range
    val rangedValue: Option[java.lang.Double] = if (hyphenIndex != -1) {
        val lowRangeStringUntruncated = inputValue.get.substring (0, hyphenIndex)
        val lowRangeString = lowRangeStringUntruncated.substring (0, scala.math.min (lowRangeStringUntruncated.length, 8) )
        scala.util.Try[java.lang.Double](lowRangeString.toDouble).toOption
    } else null
    val nonRangedValue: Option[java.lang.Double] = scala.util.Try[java.lang.Double](inputValue.get.toDouble).toOption
    val valueOptDouble: Option[java.lang.Double] = Option(rangedValue.getOrElse(nonRangedValue))
    ...
    <do something with valueOptDouble>
}
Error:(157, 89) type mismatch;
 found   : Option[Double]
 required: Double
            val valueOptDouble: Option[java.lang.Double] = Option(rangedValue.getOrElse(nonRangedValue))

我确信这可以写得更简洁,但我很困惑的是为什么最后一行会导致这个错误,因为看起来 rangedValuenonRangedValue 属于 Option[Double] 类型

感谢您的帮助

【问题讨论】:

    标签: scala types


    【解决方案1】:

    类型错误与

    rangedValue.getOrElse(nonRangedValue)
    

    因为getOrElse 这里需要Double 参数,但nonRangedValueOption[Double]。也许尝试orElse 而不是getOrElse

    val valueOptDouble: Option[Double] = rangedValue orElse nonRangedValue
    

    【讨论】:

    • 谢谢@mario,改成orElse表示编译成功,例如val valueOptDouble: Option[java.lang.Double] = rangedValue.orElse(nonRangedValue)为什么getOrElse期待Double,我认为它从第一个对象中获取了预期的类型,@987654332 @ 这也是Option[Double]?
    • nvm,我认为这是因为getOrElse 在这种情况下返回包含的值Double,而不是Option
    【解决方案2】:

    您可能想看看Scaladoc 以了解有用的组合符,例如mapflatMap

    我真的不明白你的代码做了什么,所以这里尝试解决同样的问题。
    无论如何,我认为代码应该很容易适应您的实际需求,但请随时提出任何问题或澄清问题,以便我可以编辑代码。

    def getValueFromString(inputValue: String): Option[Double] =
      inputValue.split('-').toList match {
        case raw1 :: raw2 :: Nil =>
          for {
            first <- raw1.toDoubleOption
            second <- raw2.toDoubleOption
          } yield if (first < 60.0d) first else second
        
        case _ =>
          None
    

    然后您可以将这个方法传递给原始Option[String]flatMap,如下所示:

    Some("10-30").flatMap(getValueFromString)
    // res: Option[Double] = Some(10.0d)
    

    你可以看到代码在运行here

    【讨论】:

    • 谢谢 Luis,我应该说我在 scala 2.12 上运行,所以在运行代码时出现此错误:toDoubleOption is not a member of String 但我想我理解这种方法。 1个问题,第3行的Nil有什么作用?谢谢
    • @crispo str.toDoubleOption 可以替换为 Try(str.toDouble).toOption - Nil 的目的是确保 List 恰好有两个元素,仅此而已。
    【解决方案3】:

    只要inputValue.split("-").head.toDouble

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 2019-05-07
      • 2017-12-19
      相关资源
      最近更新 更多