Scala模式匹配错误,“错误的简单模式:错误使用_ *(不允许序列模式)”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala模式匹配错误,“错误的简单模式:错误使用_ *(不允许序列模式)”相关的知识,希望对你有一定的参考价值。

我正在编写Coursera的作业,我遇到了有关Scala模式匹配的问题。

“Scala编程”一书有以下代码:

expr match { 
    case List(0, _ * ) => println("found it") 
    case _ => 
}

所以我写了一个类似的代码来计算列表中每个字符的频率:

/**
 * This function computes for each unique character in the list `chars` the number of
 * times it occurs. For example, the invocation
 *
 *   times(List('a', 'b', 'a'))
 *
 * should return the following (the order of the resulting list is not important):
 *
 *   List(('a', 2), ('b', 1)) */
 def times(chars: List[Char]): List[(Char, Int)] = {
   def addTime(char: Char, times: List[(Char, Int)]):List[(Char, Int)] = times match {
     case List(head @ (_*), (c , times), tail @ (_*)) if c == char => List(head, (c, times + 1), tail)
     case _ => List((char, 1))
 }

   if(chars.isEmpty) Nil else addTime(chars.head, times(chars.tail))
}

但是,编译器抱怨:

Error:(81, 29) bad simple pattern: bad use of _* (sequence pattern not allowed)
    case List(head @ (_*), (c , times), tail @ (_*)) if c == char => List(head, (c, times + 1), tail)

虽然我以另一种方式成功实现了这个方法,但是在2个辅助函数的帮助下,我不知道为什么不允许这个序列模式。我试过谷歌,但我找不到答案。

任何建议将不胜感激。提前致谢。

答案

任何模式匹配仅以最多一种方式分解原始值。如果case List(head @ (_*), (c , times), tail @ (_*))是合法的,它将允许headctimestail的许多选项。你的意图似乎是按顺序尝试所有这些方法,并且当守卫c == char变为真时匹配,但这不是Scala模式匹配的工作方式。

事实上,为了使规则简单,_*只允许在最后。像List(_*, c)这样的东西可以合理地允许,但事实并非如此。

以上是关于Scala模式匹配错误,“错误的简单模式:错误使用_ *(不允许序列模式)”的主要内容,如果未能解决你的问题,请参考以下文章

使用构造函数scala上的模式匹配键入不匹配

模式匹配范围在Scala与Spark udf

13scala模式匹配

Scala 匹配模式

详解 Scala 模式匹配

Spark记录-Scala模式匹配