关于Scala的解释与Option的理解

Chi*_*ang 5 scala for-comprehension

我有以下定义:

def f: Option[String] = Some(null)
Run Code Online (Sandbox Code Playgroud)

以下评估为无:

for {x:String <- f} yield {
  x
}
Run Code Online (Sandbox Code Playgroud)

以下评估为Some(null):

for {x <- f} yield {
  x
}
Run Code Online (Sandbox Code Playgroud)

以下评估为Some(null):

f.map((x:String) => x)
Run Code Online (Sandbox Code Playgroud)

我想知道为什么它们之间存在差异?

som*_*ytt 5

desugaring发生在解析器中,因此-Xprint:parser显示了差异:

$ scala -Xprint:parser
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.

scala> for (s: String <- (Some(null): Option[String])) yield s
[[syntax trees at end of                    parser]] // <console>
package $line3 {
  object $read extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    object $iw extends scala.AnyRef {
      def <init>() = {
        super.<init>();
        ()
      };
      object $iw extends scala.AnyRef {
        def <init>() = {
          super.<init>();
          ()
        };
        val res0 = (Some(null): Option[String]).withFilter(((check$ifrefutable$1) => check$ifrefutable$1: @scala.unchecked match {
  case (s @ (_: String)) => true
  case _ => false
})).map(((s: String) => s))
      }
    }
  }
}

res0: Option[String] = None
Run Code Online (Sandbox Code Playgroud)

这让我感到惊讶,因为我认为以这种方式过滤是人们想要但未实现的功能.

类型模式只是一个测试实例,因此null无法通过该测试.

没有过滤器:

scala> for (s <- (Some(null): Option[String])) yield s
[[syntax trees at end of                    parser]] // <console>
package $line4 {
  object $read extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    object $iw extends scala.AnyRef {
      def <init>() = {
        super.<init>();
        ()
      };
      object $iw extends scala.AnyRef {
        def <init>() = {
          super.<init>();
          ()
        };
        val res1 = (Some(null): Option[String]).map(((s) => s))
      }
    }
  }
}

res1: Option[String] = Some(null)
Run Code Online (Sandbox Code Playgroud)

在2.9:

$ scala29
Welcome to Scala version 2.9.3 (OpenJDK 64-Bit Server VM, Java 1.6.0_38).
Type in expressions to have them evaluated.
Type :help for more information.

scala> for (s: String <- (Some(null): Option[String])) yield s
res0: Option[String] = Some(null)
Run Code Online (Sandbox Code Playgroud)

所以在2.10.x中添加了过滤功能.

编辑:实际上,是你没有得到的:

scala> for (s: String <- (Some("x"): Option[Any])) yield s
<console>:12: error: type mismatch;
 found   : String => String
 required: Any => ?
       for (s: String <- (Some("x"): Option[Any])) yield s
                      ^
Run Code Online (Sandbox Code Playgroud)