带有类型注释的 for-comprehension 中的 Scala 异常
scala exception in for-comprehension with type annotation
我正在尝试了解在 for-comprehension 中处理空值和类型注释时的奇怪行为。
举个例子:
def f(): String = null
for {
a <- Option("hello")
b = f()
} yield (a, b)
预期结果:
//> res0: Option[(String, String)] = Some((hello,null))
但是,如果我将类型注释添加到 b
的类型
def f(): String = null
for {
a <- Option("hello")
b: String = f()
} yield (a, b)
然后我得到一个运行时异常:
//> scala.MatchError: (hello,null) (of class scala.Tuple2)
为什么会这样?在第一个示例中 b
不是隐式类型 String
吗?第二个例子中的显式类型注释有什么变化?
(注意,示例在 Scala 2.11.4 中运行)
null
不是任何实例:
scala> (null: String) match { case _: String => }
scala.MatchError: null
... 33 elided
scala> val s: String = null
s: String = null
scala> s.isInstanceOf[String]
res1: Boolean = false
http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#type-patterns
类型模式指定非空。
显示翻译的一个技巧是评论显示:
scala> for {
| a <- Option("hello")
| b: String = f()
| } yield (a, b) // show
object $read extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
import $line4.$read.$iw.$iw.f;
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
val res1 = Option("hello").map(((a) => {
val b: String = f;
scala.Tuple2(a, b)
})).map(((x) => x: @scala.unchecked match {
case scala.Tuple2((a @ _), (b @ (_: String))) => scala.Tuple2(a, b)
}))
}
}
}
scala.MatchError: (hello,null) (of class scala.Tuple2)
at $anonfun.apply(<console>:10)
at $anonfun.apply(<console>:10)
at scala.Option.map(Option.scala:145)
... 39 elided
我正在尝试了解在 for-comprehension 中处理空值和类型注释时的奇怪行为。
举个例子:
def f(): String = null
for {
a <- Option("hello")
b = f()
} yield (a, b)
预期结果:
//> res0: Option[(String, String)] = Some((hello,null))
但是,如果我将类型注释添加到 b
def f(): String = null
for {
a <- Option("hello")
b: String = f()
} yield (a, b)
然后我得到一个运行时异常:
//> scala.MatchError: (hello,null) (of class scala.Tuple2)
为什么会这样?在第一个示例中 b
不是隐式类型 String
吗?第二个例子中的显式类型注释有什么变化?
(注意,示例在 Scala 2.11.4 中运行)
null
不是任何实例:
scala> (null: String) match { case _: String => }
scala.MatchError: null
... 33 elided
scala> val s: String = null
s: String = null
scala> s.isInstanceOf[String]
res1: Boolean = false
http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#type-patterns
类型模式指定非空。
显示翻译的一个技巧是评论显示:
scala> for {
| a <- Option("hello")
| b: String = f()
| } yield (a, b) // show
object $read extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
import $line4.$read.$iw.$iw.f;
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>;
()
};
val res1 = Option("hello").map(((a) => {
val b: String = f;
scala.Tuple2(a, b)
})).map(((x) => x: @scala.unchecked match {
case scala.Tuple2((a @ _), (b @ (_: String))) => scala.Tuple2(a, b)
}))
}
}
}
scala.MatchError: (hello,null) (of class scala.Tuple2)
at $anonfun.apply(<console>:10)
at $anonfun.apply(<console>:10)
at scala.Option.map(Option.scala:145)
... 39 elided