本Option类有一个名为方法fold()。文档说:
sealed abstract class Option[+A]
fold[B](ifEmpty: ? B)(f: (A) ? B): B
Run Code Online (Sandbox Code Playgroud)
如果scala.Option为非空,则返回将f应用于此scala.Option的值的结果。否则,计算表达式ifEmpty。
该文档继续:
这等效于scala.Option映射f getOrElse ifEmpty。
但这是真的吗?有人告诉我,在某些情况下,某些类型的值存在差异,但从来没有一个体面的解释。这两种构造在不同情况下的确切情况是什么?为什么?
Option.fold比更加安全.getOrElse。您可以在.fold下面看到其中ifEmpty和f均为类型的定义B。(可能仅在scala 2.10之后引入)
@inline final def fold[B](ifEmpty: => B)(f: A => B): B =
if (isEmpty) ifEmpty else f(this.get)
Run Code Online (Sandbox Code Playgroud)
这意味着您可能不会弄乱数据类型(以下例外),
scala> val data = Option("massive data").fold(-1) { _ => 1 }
data: Int = 1
// but if i try to return different type in either of ifEmpty or f
// compiler will curse me right at my face
scala> val data = Option("massive data").fold(-1) { _ => "Let me caught by compiler" }
<console>:17: error: type mismatch;
found : String("Let me caught by compiler")
required: Int
val data = Option("massive data").fold(-1) { _ => "Let me caught by compiler" }
^
Run Code Online (Sandbox Code Playgroud)
getOrElse除非手动提供类型(以下定义中的超类型)B,否则While 并不安全。
@inline final def getOrElse[B >: A](default: => B): B =
if (isEmpty) default else this.get
Run Code Online (Sandbox Code Playgroud)
这意味着您可以返回的类型getOrElse与原始值所返回的类型不同Option[A]。
scala> val data = Option("massive data").map(_ => 1).getOrElse(List("I'm not integer"))
data: Any = 1
//you have to manually mention the type to getOrElse to restrict,
// which is not that smart in my opinion
scala> val data = Option("massive data").map(_ => 1).getOrElse[Int](List("I'm not integer"))
<console>:17: error: type mismatch;
found : List[String]
required: Int
val data = Option("massive data").map(_ => 1).getOrElse[Int](List("I'm not integer"))
^
Run Code Online (Sandbox Code Playgroud)
有趣的是,你可以返回unit从getOrElse或fold除非你在单位的口味赶上它可以在应用程序引入错误。
scala> val data = Option("massive data").fold() { _ => 1 }
data: Unit = ()
scala> val data = Option("massive data").map(_ => 1).getOrElse()
data: AnyVal = 1
Run Code Online (Sandbox Code Playgroud)
作为与 @prayagupd 答案的对立面,fold它经常邀请您以特定的方式搞乱类型。
问题在于,根据 Scala 的规则,仅ifEmpty用于推断 B,然后f检查是否合适。这意味着使用None或Nilas ifEmpty,这是很常见的,将导致它们的单例类型被用作而B不是Option/List[SomeType],无论f返回什么。
当然,有一些解决方法:B显式指定、使用Option.empty[SomeType]orNone: Option[SomeType]代替None. 或者只是使用模式匹配。
| 归档时间: |
|
| 查看次数: |
605 次 |
| 最近记录: |