我想知道为什么我不能在包含空值(字符串)的Spark(2.1)行上进行模式匹配:
val r = Row(null:String)
r match {case Row(s:String) => println("row is null")}
scala.MatchError:[null](类 org.apache.spark.sql.catalyst.expressions.GenericRow)
答案 0 :(得分:8)
Row
在这里并没有发挥重要作用,我们可以简化:
val r = null: String
r match {case s:String => println("s is null")}
您可以检查模式匹配是否仍然失败。这是因为s: String
等类型模式是specifically defined not to match null
:
类型模式T具有以下形式之一:
- 对C,p.C或T#C类的引用。此类型模式匹配给定类的任何非空实例 ...
isInstanceOf
的行为也是这样的:null.isInstanceOf[String]
是false
。
因此,如果您想匹配null
,您可以
1)准确使用null
作为模式:
r match {
case s: String => println("r is not null")
case null => println("r is null")
}
2)使用像_
这样的“全能”模式或变量:
r match {
case s: String => println("r is not null")
case s => println("matches only if r is null or not a String")
}
或者如果我们放回Row
,你就会写
r match {
case Row(s: String) => println("r contains non-null")
case Row(null) => println("r contains null")
}
答案 1 :(得分:0)
你可以,但模式应该完全匹配Row(null)
。
scala> r match { case Row(null) => "matched" }
res1: String = matched
你是对的,更通用的模式不起作用。
scala> r match { case Row(s: String) => "matched" }
scala.MatchError: [null] (of class org.apache.spark.sql.catalyst.expressions.GenericRow)
... 50 elided
我认为这是因为null
会给你Any
类型来匹配(并且涉及某种类型的魔法我无法准确解释)。
scala> Row.unapplySeq(r)
res2: Some[Seq[Any]] = Some(WrappedArray(null))