首页 > 解决方案 > Scala Option.fold 在函数内外表现不同

问题描述

采取简单的功能:

def makeUpper(input: Option[String]): String = 
    input.fold("b"){ _.toUpperCase }

makeUpper(Some("a"))   // A
makeUpper(None)        // b

这正如预期的那样。

现在,相同的代码,但在函数之外:

Some("a").fold("b"){ _.toUpperCase }   // A
None.fold("b"){ _.toUpperCase }        // error: value toUpperCase is not a member of Nothing

笔记:

Option.empty[String].fold("b"){ _.toUpperCase }   // b

问题:

  1. 为什么会有不同的行为?为什么函数外的错误?

该函数是否将输入 None 转换为“确定的”Option.empty [String]?

  1. 处理返回 Option(Some 或 None)的函数返回的正确方法是什么......我们是否总是必须在另一个函数中处理返回值以避免上述问题?

我错过了什么?

标签: scalaoptional

解决方案


None定义为:

case object None extends Option[Nothing]

因此,当您在“内容”上调用方法时,None您正在调用 type 值的方法Nothing。此类型没有方法toUpperCase,因此您会收到错误消息。

然而Nothing,它与每种类型兼容,并且Option与其类型参数协变,因此Option[Nothing]Option[String]. 这就是为什么None可以传递给你的makeUpper方法。一旦知道内容的类型,就可以StringtoUpperCase其上调用方法。


推荐阅读