2010-12-22 99 views
11

我正在學習一些斯卡拉代碼,發現這種方法讓我感到困惑。在比賽聲明中,什麼是[email protected]構造?它包含什麼樣的價值?當我打印它的差異不是tail,但如果我用尾部替換它,該函數返回差異結果。有人可以解釋它是什麼,並指出我是一個正確的資源來理解它嗎? (我知道我可以在谷歌搜索,但不知道要尋找什麼。)斯卡拉「匹配」幫助

def flatMapSublists[A, B](ls: List[A])(f: (List[A]) => List[B]): List[B] = 
    ls match { 
     case Nil => Nil 
     case [email protected](_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f) 
    } 
+0

`@`通常用於註釋中,但我在這裏沒有看到類似的東西...... – 2010-12-22 20:32:06

回答

28

我會稱之爲「吃你的蛋糕,讓它太操作」。在模式匹配的任何級別,您可以給一個零件一個名稱(在@之前)並將其進一步解構(在@之後)。例如想象你要匹配3個元素的列表,你需要的第二個元素,而是要記錄整個列表:

something match { 
    case [email protected](_,elem,_) => log("matching:" + list); elem  
    case _ => error("not found") 
} 

沒有此功能,你必須寫類似

something match { 
    case List(a,elem,b) => log("matching:" + List(a,elem,b)); elem  
    case _ => error("not found") 
} 

正如您所看到的,我們需要命名第一個和第三個元素,僅僅是因爲我們需要它們在右側獲取具有相同結構的列表,這是樣板。如果您可以在整個結構中指定一個名稱(list),並且結構中還有更深的零件(elem),並且您在右側需要這兩個零件時更容易和清楚。

8

在這種情況下,子列表成爲整個列表(_ :: tail)命名變量。尾巴是列表的尾部。我不確定這裏是否有'@'的專用名稱。

我沒有真正看到子列表的目的,因爲你可以直接引用ls

聲明:我是scala新手。我希望我有這個權利。

+1

Haskell(也可以是ML)也是如此。 – delnan 2010-12-22 20:37:02

+0

嘿,謝謝你的回答。這兩個答案幫助我理解了它。 – 2010-12-22 21:12:30