我有以下定义:
def f: Option[String] = Some(null)
以下内容的求值结果为None:
for {x:String <- f} yield {
x
}
以下表达式的求值结果为 Some(null):
for {x <- f} yield {
x
}
以下表达式的结果是Some(null):
f.map((x:String) => x)
我想知道它们之间的差异是什么?
我有以下定义:
def f: Option[String] = Some(null)
for {x:String <- f} yield {
x
}
for {x <- f} yield {
x
}
f.map((x:String) => x)
我想知道它们之间的差异是什么?
-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
这让我感到惊讶,因为我认为以这种方式进行过滤是人们想要的功能,但尚未实现。
类型模式只是一个instanceof测试,所以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)
$ 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)
因此,在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
^
好的...首先要说的是,“在Scala世界里,尽可能远离null怪兽”。它们很危险。
现在...为了理解这种行为,在Scala shell中尝试的第一件事是以下内容:
scala> val n = null
n: Null = null
那么,在Scala中,null
是Null
类的一个实例。
现在,让我们看看当我们将这个null
与Option
混合时会发生什么。
scala> val nullOpt1 = Option(null)
nullOpt1: Option[Null] = None
scala> val nullOpt2 = Some(null)
nullOpt2: Some[Null] = Some(null)
null
包装成Option
...所以他们允许他们明确地
使用Some.apply
将null
包装成Option
。而Option.apply
的使用行为更加"智能",当您尝试包装null
时,它会给您一个None
。
现在...让我们先看看如何为Option
实现map
,
final def map[B](f: A => B): Option[B] =
if (isEmpty) None else Some(f(this.get))
Some
中有什么“值”(即使为空),this.get
都将返回该“值”,在本例中,f
只是x => x
,因此结果为Some(null)
。 - sarveshseri