Scala:如何简化嵌套模式匹配语句
Scala: How to simplify nested pattern matching statements
我正在用 Scala 编写一个 Hive UDF(因为我想学习 scala)。为此,我必须覆盖三个函数:evaluate
、initialize
和 getDisplayString
.
在初始化函数中我必须:
- 接收
ObjectInspector
和 return 一个 ObjectInspector
的数组
- 检查数组是否为空
- 检查数组大小是否正确
- 检查数组是否包含正确类型的对象
为此,我使用了模式匹配并提出了以下函数:
override def initialize(genericInspectors: Array[ObjectInspector]): ObjectInspector = genericInspectors match {
case null => throw new UDFArgumentException(functionNameString + ": ObjectInspector is null!")
case _ if genericInspectors.length != 1 => throw new UDFArgumentException(functionNameString + ": requires exactly one argument.")
case _ => {
listInspector = genericInspectors(0) match {
case concreteInspector: ListObjectInspector => concreteInspector
case _ => throw new UDFArgumentException(functionNameString + ": requires an input array.")
}
PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(listInspector.getListElementObjectInspector.asInstanceOf[PrimitiveObjectInspector].getPrimitiveCategory)
}
}
尽管如此,我的印象是函数可以变得更清晰,并且通常更漂亮,因为我不喜欢缩进级别太多的代码。
是否有惯用的 Scala 方法来改进上面的代码?
模式通常包含其他模式。这里x
的类型是String.
scala> val xs: Array[Any] = Array("x")
xs: Array[Any] = Array(x)
scala> xs match {
| case null => ???
| case Array(x: String) => x
| case _ => ???
| }
res0: String = x
"any number of args" 的成语是 "sequence pattern",它匹配任意参数:
scala> val xs: Array[Any] = Array("x")
xs: Array[Any] = Array(x)
scala> xs match { case Array(x: String) => x case Array(_*) => ??? }
res2: String = x
scala> val xs: Array[Any] = Array(42)
xs: Array[Any] = Array(42)
scala> xs match { case Array(x: String) => x case Array(_*) => ??? }
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
... 32 elided
scala> Array("x","y") match { case Array(x: String) => x case Array(_*) => ??? }
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
... 32 elided
不应将此答案解释为提倡匹配以返回类型安全。
我正在用 Scala 编写一个 Hive UDF(因为我想学习 scala)。为此,我必须覆盖三个函数:evaluate
、initialize
和 getDisplayString
.
在初始化函数中我必须:
- 接收
ObjectInspector
和 return 一个ObjectInspector
的数组
- 检查数组是否为空
- 检查数组大小是否正确
- 检查数组是否包含正确类型的对象
为此,我使用了模式匹配并提出了以下函数:
override def initialize(genericInspectors: Array[ObjectInspector]): ObjectInspector = genericInspectors match {
case null => throw new UDFArgumentException(functionNameString + ": ObjectInspector is null!")
case _ if genericInspectors.length != 1 => throw new UDFArgumentException(functionNameString + ": requires exactly one argument.")
case _ => {
listInspector = genericInspectors(0) match {
case concreteInspector: ListObjectInspector => concreteInspector
case _ => throw new UDFArgumentException(functionNameString + ": requires an input array.")
}
PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(listInspector.getListElementObjectInspector.asInstanceOf[PrimitiveObjectInspector].getPrimitiveCategory)
}
}
尽管如此,我的印象是函数可以变得更清晰,并且通常更漂亮,因为我不喜欢缩进级别太多的代码。
是否有惯用的 Scala 方法来改进上面的代码?
模式通常包含其他模式。这里x
的类型是String.
scala> val xs: Array[Any] = Array("x")
xs: Array[Any] = Array(x)
scala> xs match {
| case null => ???
| case Array(x: String) => x
| case _ => ???
| }
res0: String = x
"any number of args" 的成语是 "sequence pattern",它匹配任意参数:
scala> val xs: Array[Any] = Array("x")
xs: Array[Any] = Array(x)
scala> xs match { case Array(x: String) => x case Array(_*) => ??? }
res2: String = x
scala> val xs: Array[Any] = Array(42)
xs: Array[Any] = Array(42)
scala> xs match { case Array(x: String) => x case Array(_*) => ??? }
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
... 32 elided
scala> Array("x","y") match { case Array(x: String) => x case Array(_*) => ??? }
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230)
... 32 elided
不应将此答案解释为提倡匹配以返回类型安全。