我有3个函数,kk expect Array[Byte]
或List[Array[Byte]]
,所以我做了一个模式匹配,
def gg (a :Array[Byte]) = "w"
def ff (a :List[Array[Byte]]) = "f"
def kk(datum : Any) = datum match {
case w : Array[Byte] => gg(w)
case f :List[Array[Byte]] => ff(f)
case _ => throw new Exception("bad data")
}
我尝试编译代码时遇到错误:
非变量类型参数类型模式中的List [Any] List [List [Any]](List [List [Any]]的基础)未被选中,因为它被删除删除
所以我将kk
函数构造为流动,现在可以编译:
def kk(datum : Any) = datum match {
case w : Array[Byte] => gg(w)
case f :List[_] => ff(f.asInstanceOf[List[Array[Byte]]])
case _ => throw new Exception("bad data")}
我的问题:
1:是我当前版本的kk
是用于为List做模式匹配的惯用方法,如果没有,有人可以展示如何做到这一点吗?
2:如果我想模式匹配List[Any]
和List[List[Any]]
,我怎么能这样做?如果我的数据类型为(ff(f.asInstanceOf[List[Array[Byte]]])
)
List[Byte]
可能会导致错误
答案 0 :(得分:1)
有几件事要说:
T
和List[T]
很少用作替代品。如果是您的情况,请尝试将它们带到至少Either
或更具体的案例类别。如果您确实Any
没有任何其他预先安排好的知识而且您确实需要确定List[Byte]
或List[List[Byte]]
,那么您唯一的选择就是检查像这样的集合:
class ListMatch[A](f: Any => Option[A]) {
def unapply(obj: Any) = obj match {
case seq: List[_] =>
seq.foldLeft[Option[List[A]]](Some(Nil)) {
(optSeq, elem) => for {
seq <- optSeq
elem <- f(elem)
} yield elem :: seq
} map (_.reverse)
case _ => None
}
}
val matchByte: PartialFunction[Any, Byte] = {
case b: Byte => b
}
val ByteList = new ListMatch(matchByte.lift)
val ByteListList = new ListMatch(ByteList.unapply)
因此您将更改定义为
def kk(datum: Any) = datum match {
case ByteList(w) => gg(w)
case ByteListList(f) => ff(f)
case _ => "bad data"
}
您可以尝试以下测试以确保正确性:
kk(1) // bad data
kk(List(1.toByte)) // w
kk(List(List(1.toByte))) // f
kk(List(1.toByte, 2)) // bad data
kk(List(1.toByte), List(2)) // bad data