2012-10-24 187 views
8

我對Scala中的模式匹配有點困惑。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 =() 

這當前只打印一行輸出。它不應該在列表的每個元素上運行/模式匹配嗎?

編輯:我解決了編譯錯誤,並從REPL複製輸出。

+0

你打電話給simple_fun – smk

+0

@SajitKunnumkal我已編輯我的文章回答你的問題。 –

回答

22

除非您以某種方式反覆調用simple_fun,否則您在那裏的模式將匹配第一個元素,僅此而已。爲了得到它,以配合整個列表,你可以得到simple_fun遞歸調用自身,就像這樣:

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編譯器可以推斷他們,離開你更少的混亂,更可讀的代碼。

作爲一個小方面,重複調用println這樣的函數並不是特別有用 - 因爲它都是關於副作用的。一個更習慣的方法是讓該函數構造一個描述列表的字符串,然後用一次調用將其輸出到println - 所以副作用保存在一個明確定義的位置。這樣的事情會是一個方法:

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

println(simple_fun(simple_list)) 
+1

謝謝。所以模式匹配只會被調用一次,而不是列表中的每個元素。此外,我不得不明確地向simple_fun添加一個返回類型(Unit),以便能夠遞歸調用它。 –

+0

沒問題!是的,我意識到(關於需要返回類型的遞歸函數),同時對答案進行了一些澄清,以便對其進行修改。您是否在coursera.org上關注過scala課程? – Russell

+0

我知道println會產生副作用。我只是爲了這個簡單的例子而添加了它。我同意,如果想要純粹的功能,它不應該成爲真正的代碼的一部分。 –

-1

我認爲有以下應該工作:

def flatten(l: List[_]): List[Any] = l match { 
    case Nil => Nil 
    case (head: List[_]) :: tail => flatten(head) ::: flatten(tail) 
    case head :: tail => head :: flatten(tail) 
} 

的第一行是無匹配,因此,如果我們沒有發現任何不返回任何內容。 第二行將標識列表列表並調用展平方法並展平列表列表。

+1

這個問題得到了回答,4年前答案被接受。你的回答不僅遲到了晚會,它也忽略了這一點。問題是關於簡單模式匹配。關於嵌套列表的問題沒有任何問題。 – jwvh