Scala中列表上的模式匹配

问题描述:

我对Scala列表中的模式匹配有些困惑.

I'm a little confused regarding pattern matching on a list in Scala.

例如.

    val simplelist: List[Char] = List('a', 'b', 'c', 'd')

    //> simplelist  : List[Char] = List(a, b, c, d)

    def simple_fun(list: List[Char]) = list match {
           case (x:Char) :: (y:List[Char]) => println(x)
           case _ => Nil
     }                                                 
   //> simple_fun: (list: List[Char])Any

   simple_fun(simplelist)                            

   //> a
   //| res0: Any = ()

这当前只打印一行输出.它不应该在List的每个元素上运行/模式匹配吗?

This currently prints only one line of output. Should it not run/pattern match on each element of the List ?

我修复了编译错误,并复制了REPL的输出.

I fixed the compile errors and copied the output from the REPL.

除非您以某种方式重复调用 simple_fun ,否则您所拥有的内容将与第一个元素匹配,仅此而已.为了使其与整个列表匹配,您可以使 simple_fun 递归调用自身,如下所示:

Unless you are repeatedly calling simple_fun in some way, what you have there will pattern match the first element and nothing more. To get it to match the whole list, you can get simple_fun to call itself recursively, like this:

val simplelist: List[Char] = List('a', 'b', 'c', 'd')

def simple_fun(list: List[Char]): List[Nothing] = list match {
  case x :: xs => {
    println(x)
    simple_fun(xs)
  }
  case _ => Nil 
}

请注意,由于Scala编译器可以推断出它们,因此我还省略了一些类型,从而使您的代码更简洁,可读性更强.

Note I've also left out some of the types as the Scala compiler can infer them, leaving you with less cluttered, more readable code.

作为一个小小的注解,在这样的函数内反复调用 println 并不是特别有用-因为它全都与副作用有关.一种更惯用的方法是让函数构造一个描述列表的字符串,然后通过一次调用 println 的方式将其输出-这样,副作用就可以保存在一个定义明确的位置.这样的事情将是一种方法:

As a small side-note, calling println repeatedly inside the function like that is not particularly functional - as it is all about side effects. A more idiomatic approach would be to have the function construct a string describing the list, which is then output with a single call to println - so the side-effects are kept in a single well-defined place. Something like this would be one approach:

def simple_fun(list: List[Char]):String = list match {
  case x :: xs => x.toString + simple_fun(xs)
  case Nil => ""
}

println(simple_fun(simple_list))