2012-09-20 115 views
0

我遇到過這個scala代碼,我試着弄清楚它做了什麼,除了事實上它返回一個int。我不確定這三行:解釋一些scala代碼 - 初學者

l match { 
    case h :: t => 
    case _ => 0 

功能:

def iterate(l: List[Int]): Int = 
    l match { 
    case h :: t => 
    if (h > n) 0 
    case _ => 0 
} 
+0

去通過斯卡拉之旅HTTP ://www.scala-lang.org/node/120。另外,http://www.artima.com/scalazine/articles/pattern_matching.html –

+4

您的代碼不應該編譯,因爲'if(h> n)0'不是'Int'類型(缺少其他類型爲'Int'的情況')和'n'是未知的。 –

+0

'head :: tail'模式匹配列表。對於'List(1,2,3)'它是'1 :: List(2,3)',對於'List(1)'它是'1 :: List()'(或'1 :: Nil' ),對於List(),它不匹配。 「_」與「其他」匹配。 – ron

回答

14

首先,定義了一個名爲iterate功能,您所指定的返回類型爲Int。它具有類型List[Int]的參數1,參數l

List類型在整個函數式編程中都很突出,它的主要特點是它具有高效的前置,並且易於將任何List分解成頭部和尾部。頭將是列表中的第一個元素(如果非空),尾部將是List(本身是List)的其餘部分 - 這對於在List上運行的遞歸函數非常有用。

match被稱爲模式匹配。它本質上是在C-ISH語言switch語句,但更強大 - 在switch限制你常數(至少在C時一樣),但目前還沒有這樣的限制與match

現在,您的第一個case您有h :: t - ::被稱爲「cons」,這是函數式編程的另一個術語。當您通過預先從另一個List創建新的List時,可以使用::運算符來完成此操作。

實施例:

val oldList = List(1, 2, 3) 
val newList = 0 :: oldList // newList == List(0, 1, 2, 3) 

在Scala中,與一個:結束操作符是真正的右手側的一個方法,所以0 :: oldListoldList.::(0)等效 - 的0 :: oldList是語法糖,使得它更容易讀。

我們可能已經定義oldList

val oldList = 1 :: 2 :: 3 :: Nil 

其中Nil表示空List。打破這種分解成以下步驟:

  1. 3 :: Nil首先計算,創建List(3)其具有頭3和尾空的等效。
  2. 2被添加到上面的列表中,創建一個新的列表,頭2和尾List(3)
  3. 1被前置,創建一個頭1和尾部List(2, 3)的新列表。

所得的List(1, 2, 3)List被分配給val oldList

現在,當您使用::模式匹配你基本上是一個分解成List頭部和尾巴,就像我們如何創建的List上述相反。在這裏當你做

l match { 
    case h :: t => ... 
} 

你說如果可能分解l成頭和尾。如果成功分解,則可以使用這些變量ht來做任何你想做的事情。通常你會做類似於h的行爲,並在t上調用遞歸函數。

這裏有一點要注意的是,你的代碼將無法編譯..你做一個if (h > n) 0但目前還沒有明確的else所以會發生什麼是你的代碼看起來像這樣的編譯器:

if (h > n) 0 
else { } 

其中有鍵入AnyVal0和「nothing」的常見超類型),違反了您的Int保證 - 您將不得不添加具有某個失敗值的else分支或其他內容。

第二個case _ =>就像switch中的default,它捕獲任何在第一個case中頭/尾分解失敗的東西。

您的代碼基本上做到這一點:

  1. 採取lList參數,看看它是否可以分解爲頭部和尾部。
  2. 如果可能,比較頭部對(我認爲是)外部範圍內稱爲n的變量。如果它比n越大,函數返回0(您需要添加會發生什麼,如果它不是更大)
  3. 如果它不能被分解,函數返回0
+0

感謝您的詳細解釋。 –