2017-02-03 70 views
0

我正在閱讀和練習斯卡拉,我發現這個blog瞭解斯卡拉的下劃線和星號魔法

閱讀有關創作謂詞我看到這段代碼的一部分

def complement[A](predicate: A => Boolean) = (a: A) => !predicate(a) 

def any[A](predicates: (A => Boolean)*): A => Boolean = 
    a => predicates.exists(pred => pred(a)) 

def none[A](predicates: (A => Boolean)*) = complement(any(predicates: _*)) 

def every[A](predicates: (A => Boolean)*) = none(predicates.view.map(complement(_)): _*) 

我有一個Python的背景和想了解下劃線和星號的含義單獨或一起使用時,這是相當奇怪的是有意義的,特別對於的定義。

+0

'_'一般是指「東西的名字我不關心」。你可能想要探索這個答案的所有可能的含義:http://stackoverflow.com/a/8001065/3314107 – stefanobaghino

回答

1

SomeExpression*意味着

_可以用「0個或多個元素的序列」指定

none的參數是「謂詞的序列「我們並不需要命名的參數」包含0個或更多元素「,而」謂詞「是一個函數,它需要A並返回Boolean

any的參數是一個數組,所以傳入的值必須被轉換成一個陣列,其由_*

參數做every是一個數組,其名稱並不重要,因爲只有一。它可以傳遞給complement_

1
def any[A](predicates: (A => Boolean)*) 

產生相同的功能

def any[A](predicates: Seq[A => Boolean]) 

除了你可以這樣調用它any(a, b, c)代替any(List(a, b, c))(編譯變換調用點)。

鑑於any是可變參數函數,調用any(a)進入any的主體與predicates = List(a)。但如果a已經是一個序列,這不是你想要的。這就是: _*表示法:它告訴Scala編譯器「將它視爲可變參數的一系列參數」。

這大致相當於在Python編寫,

def complement(predicate): 
    return lambda a: not predicate(a) 

def any_(*predicates): 
    return lambda a: any(pred(a) for pred in predicates) 

def none(*predicates): 
    return complement(any_(*predicates)) 

def every(*predicates): 
    return none(*map(complement, predicates)) 
+1

'Seq',而不是'Array'。 –

+0

@AlexeyRomanov對,我的錯誤。 Array可以通過'@ varargs'註釋來實現Java的可比性,但是它對於普通的Scala代碼來說是'Seq'。 – ephemient

+0

** **每個**的定義在同一行中使用'_'和'_ *'是什麼意思? ** complement **只接受一個謂詞,但在這種情況下不是'_'是一個Seq,這就是爲什麼後面可以使用'_ *'?最後一行是最難理解的。 –