2

在编写的 Option 类文档中,以下两个示例是等效的:

val name: Option[String] = request getParameter "name"
val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
println(upper getOrElse "")

val upper = for {
  name <- request getParameter "name"
  trimmed <- Some(name.trim)
  upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
} yield upper
println(upper getOrElse "")

但我不明白它们如何等效:在第一个代码块request getParameter "name"返回类型实例Option[String],但在第二个代码块语句name <- request getParameter "name"返回类型实例String(我假设因为下一个语句调用变量trim上的方法(未定义))。nametrimOption[String]

4

2 回答 2

5

for ... yield从理解到map/flatMap方法调用的转换由编译器完成。不需要OptionIterable; 在这种情况下,唯一需要的是Option拥有map/flatMap方法:

  • flatMap->如果在同一个for块中有更多的调用
  • map如果是最后一个

我们可以像这样创建自己的MyOption类:

case class MyOption[+T](value: T) {
  def flatMap[A](f: T => MyOption[A]): MyOption[A] = f(value)
  def map[A](f: T => A): MyOption[A] = MyOption(f(value))
  override def toString = s"Some($value)"
}

然后:

val result = for {
  a <- MyOption("one")
  b <- MyOption("two")
} yield a + "," + b
println(result)
// prints: Some(one,two)
于 2013-05-12T01:30:54.073 回答
1

Option是一个Iterable(伴生对象中有一个隐式option2Iterable方法Option),这就是它可以在someVar <- someOption子句中使用的原因。事实上,那个箭头的意思是“从右边的集合中取出元素”。

所以你是对的,name在第二个例子中是一个String.

在第一个中,您可以看到还有map其他Iterable方法用于Option. 它与下面的表达式基本相同for,但直接调用方法,而for只是语法糖,由编译器翻译成方法调用链。

于 2013-05-11T19:38:38.313 回答