Scala map操作出现scala.MatchError的原因及解决方法
解决Scala的MatchError问题
嘿,我来帮你拆解这个错误的原因和修复方法:
为什么会出现MatchError?
你写的map操作里的模式匹配没有覆盖所有可能的元素情况!
你的days列表里有n1=2的元素(比如(2,(1,aa))),但你只给了一个case去匹配n1!=2的元素。map要求列表里的每一个元素都必须被匹配到并返回结果,当遇到n1=2的元素时,没有对应的case能接住它,Scala就直接抛出MatchError了。
几种修复方式任你选
方式1:用collect代替map(最推荐)
collect就是专门干这个事的——它会自动跳过不匹配的元素,只对符合条件的元素做转换,完美适配你的需求:
val days = List((1, (2, "a")), (1, (3, "b")), (1, (1, "c")), (2, (1, "aa")), (2, (2, "bb"))) val r = days collect { case (n1, (n2, st)) if(n1!=2) => s"st = $st" }
运行后r会得到:List(st = a, st = b, st = c)
方式2:先过滤再映射
如果你喜欢分步处理,可以先用filter把n1!=2的元素挑出来,再对筛选后的列表做map,这样就不会有不匹配的元素了:
val days = List((1, (2, "a")), (1, (3, "b")), (1, (1, "c")), (2, (1, "aa")), (2, (2, "bb"))) val r = days.filter { case (n1, _) => n1 !=2 }.map { case (_, (_, st)) => s"st = $st" }
这个结果和方式1完全一样,适合需要清晰看到过滤步骤的场景。
方式3:给不匹配的元素加默认处理
如果你不想跳过n1=2的元素,而是想给它们一个默认输出,那就加一个兜底的case:
val days = List((1, (2, "a")), (1, (3, "b")), (1, (1, "c")), (2, (1, "aa")), (2, (2, "bb"))) val r = days map { case (n1, (n2, st)) if(n1!=2) => s"st = $st" case (_, (_, st)) => s"ignored st = $st" // 处理所有n1=2的元素 }
这时候r的结果会包含所有元素:List(st = a, st = b, st = c, ignored st = aa, ignored st = bb)
小总结
- 要处理列表里部分元素的转换,优先用
collect,这是Scala里最地道的写法; - 分步处理就用
filter + map; - 要是不想丢元素,一定要保证模式匹配覆盖所有可能的情况,加个兜底case就行~
内容的提问来源于stack exchange,提问作者BAE
相关产品推荐
相关产品推荐

