我正在编写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个辅助函数的帮助下,我不知道为什么不允许这个序列模式。我试过谷歌,但我找不到答案。
任何建议将不胜感激。提前谢谢。
答案 0 :(得分:3)
任何模式匹配仅以最多一种方式分解原始值。如果case List(head @ (_*), (c , times), tail @ (_*))
合法,则会为head
,c
,times
和tail
提供多种选项。您的意图似乎是按顺序尝试所有这些方法,并在保护c == char
变为真时匹配,但这不是Scala模式匹配的工作方式。
事实上,为了简化规则,_*
只允许在最后。像List(_*, c)
这样的东西可以合理地允许,但它不是。