2017-02-03 4 views
0

Ich lese und übe Scala, und ich fand diese blog.Understanding und Sternchen Magie Scala

Lesen der Teil über Composing Prädikate ich dieses Stück Code sehen

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(_)): _*) 

Ich habe einen Hintergrund Python und möchte die Bedeutung von Unterstrich und Sternchen verstehen, wenn sie allein oder zusammen verwendet werden, es recht ist seltsam, um es sinnvoll zu machen, speziell für keine und alle Definitionen.

+0

'_' im Allgemeinen bedeutet "etwas, dessen Namen ich nicht interessieren". Vielleicht möchten Sie diese Antwort in Bezug auf alle möglichen Bedeutungen erkunden: http://stackoverflow.com/a/8001065/3314107 – stefanobaghino

Antwort

1

SomeExpression* bedeutet „eine Folge von 0 oder mehr Elementen“

_ kann verwendet werden, um anzugeben, „einen Parameter, die wir nicht brauchen, um zu Name“ von Prädikaten

Der Parameter none ist „eine Sequenz enthält 0 oder mehr Elemente ", und ein" Prädikat "ist eine Funktion, die A nimmt und zurückgibt.

Der Parameter any ist ein Array, so muss der übergebene Wert auf ein Array umgewandelt werden, die durch _*

Der Parameter every wird ein Array, dessen Name erfolgt wichtig ist nicht, weil nur dort ist ein. Es kann als _

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

erzeugt die gleiche Funktion wie

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

außer complement weitergegeben werden, dass Sie es wie any(a, b, c) statt any(List(a, b, c)) nennen kann (der Compiler wandelt die Aufrufstellen).

Vorausgesetzt, dass any eine Varargs-Funktion ist, ruft any(a) den Körper von any mit predicates = List(a). Aber wenn a bereits eine Sequenz ist, ist dies nicht das, was Sie wollen. Das ist, was die : _* Notation ist: es sagt dem Scala-Compiler "behandeln Sie dies als eine Folge von Parametern für Varargs".

Das in Python entspricht in etwa, zum Schreiben

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', nicht' Array'. –

+0

@AlexeyRomanov Richtig, mein Fehler. 'Array' ist möglich mit einer' @varargs' Annotation für Java Vergleichbarkeit, aber es ist 'Seq' für einfachen Scala Code. – ephemient

+0

Was ist mit der Definition für ** alle ** wo '_' und' _ * 'in der gleichen Zeile verwendet werden? ** complement ** akzeptiert nur ein Prädikat, ist aber in diesem Kontext nicht '_' ein Seq, weshalb später '_ *' verwendet werden kann? Diese letzte Zeile ist am schwierigsten zu verstehen. –