scala 选项和数据类型

Posted

技术标签:

【中文标题】scala 选项和数据类型【英文标题】:scala Option and datatypes 【发布时间】: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] 类型

感谢您的帮助

【问题讨论】:

【参考方案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

【讨论】:

以上是关于scala 选项和数据类型的主要内容,如果未能解决你的问题,请参考以下文章

Scala系统学习:Scala数据类型

Scala 基础 :变量和数据类型

Scala之数据类型

Scala基础——常用数据类型

Scala学习(变量和数据类型流程控制)

Scala学习(变量和数据类型流程控制)