2017-06-24 2 views
2

Um scala besser kennen zu lernen, stieß ich auf ein Verhalten, das ich nicht erklären kann. Der Code unten funktioniert:Warum passiert einige Funktionen in scala _

def triple(x: Double) = 3 * x 
Array(3.14,1.42,3.9).map(triple) 

jedoch Wenn ich die scala ceil Funktion in Mathematik-Bibliothek aufrufen, dann werde ich brauchen, um einen Pass _ für sie

def valueAtOneQuarter(f: (Double)=> Double) = f(0.25) 
valueAtOneQuarter(sqrt _) 

zu arbeiten Was ist das Besondere _ in diesem Zusammenhang vom Funktionsaufruf im früheren Code.

+2

es tatsächlich funktioniert gut für mich ohne Unterstrich in beiden Fällen – Dima

+0

Die Erweiterung funktioniert für mich auch und passiert automatisch, es gibt keine Notwendigkeit, _ zu verwenden, wie Dima sagte. –

Antwort

3

Der Unterstrich ist eigentlich zu einer Funktion erweitert.

So sqrt _ wird in die Funktion a => sqrt(a) umgewandelt.

Sie werden feststellen, dass diese erweiterte Funktion dem Parametertyp f der valueatonquarter-Methode entspricht. Normalerweise wird der Unterstrich manchmal benötigt, um dem Compiler zu signalisieren, dass er die Methode (eine Methode wird mit def deklariert) in eine Funktion umwandelt (Methoden und Funktionen sind ähnlich, aber nicht das Gleiche). Der Compiler wird versuchen, die Methode automatisch in eine Funktion für Sie zu konvertieren, aber in einigen Fällen benötigt er zusätzliche Zeiger (wie eine explizite Typdeklaration oder _). Sehen Sie hier für eine vollständige Erklärung von eta Erweiterung und Teilfunktionen: https://medium.com/@sinisalouc/on-method-invocations-or-what-exactly-is-eta-expansion-1019b37e010c

+0

Dies beantwortet nicht die Frage, warum es Unterstreichung in einem Fall erfordert, aber nicht in der anderen. – Dima

+0

Danke Dima - aktualisierte Antwort. – jsdeveloper

1

Eine Methode und eine Funktion sind nicht in Scala identisch.

Sie definieren eine Methode, um diese Art und Weise:

def method(x:Double):Double = ... 

Aber Sie definieren eine Funktion auf diese Weise mit:

val func = (x: Double):Double => {...} 

wenn Sie eine Funktion als Parameter an eine Methode übergeben es eine Funktion sein muss , aber keine Methode.

Sie müssen also Unterstreichung verwenden, um eine Funktion aus einer Methode zu machen.

Manchmal verwendet Scala die Funktion "Eta Expansion", um die Methode automatisch in eine Funktion umzuwandeln. Aber in einigen Fällen müssen Sie es manuell tun

+0

Danke scheint _ hat unterschiedliche Bedeutung in verschiedenen Kontext in Scala. es ist fast wie wenn es eine Lücke gab _ ist die Antwort – jtkSource

1

Antwort, da die vorhandenen Antworten nicht wirklich erklären, wenn _ benötigt wird, nur "manchmal" oder "in einigen Fällen".

Ein sehr wichtiges Konzept in Scala zu verstehen ist erwarteten Typ. In Ihrem ersten Beispiel ist der erwartete Typ für das Argument mapDouble => B mit einigen unbekannten B; in der Sekunde ist es Double => Double. Wenn der erwartete Typ ein Funktionstyp ist und ein Methodenname übergeben wird, wird er automatisch in eine Funktion umgewandelt. So, wie Kommentare sagen, funktioniert das zweite Beispiel ohne _. Es ist nur erforderlich, wenn es kein erwarteter Typen, sagt

val f = sqrt _ 

Es kann auch Probleme sein, wenn das Verfahren überlastet ist, aber es nur das Hinzufügen _ wird in der Regel nicht funktionieren entweder; Stattdessen geben Sie den Argumenttyp an, um anzuzeigen, welche Methode verwendet wird, z. max(_: Int, _: Int) oder max(_: Double, _: Double).

Dank scheint _ hat unterschiedliche Bedeutung in anderem Zusammenhang in scala

Ja, ziemlich viele: What are all the uses of an underscore in Scala?

Verwandte Themen