Suche…


Bemerkungen

Scala hat erstklassige Funktionen.

Unterschied zwischen Funktionen und Methoden:

Eine Funktion ist keine Methode in Scala: Funktionen sind ein Wert und können als solcher zugewiesen werden. Methoden, die mit def erstellt wurden, müssen hingegen zu einer Klasse, einem Merkmal oder einem Objekt gehören.

  • Funktionen werden zu einer Klasse kompiliert, die eine Eigenschaft (wie Function1 ) zur Kompilierzeit erweitert, und zur Laufzeit in einen Wert instanziiert. Methoden dagegen sind Mitglieder ihrer Klasse, ihres Merkmals oder Objekts und existieren nicht außerhalb davon.
  • Eine Methode kann in eine Funktion konvertiert werden, eine Funktion kann jedoch nicht in eine Methode konvertiert werden.
  • Methoden können eine Typparametrierung haben, Funktionen dagegen nicht.
  • Methoden können Parameter-Standardwerte haben, Funktionen dagegen nicht.

Anonyme Funktionen

Anonyme Funktionen sind Funktionen, die definiert sind, aber keinen Namen erhalten.

Das Folgende ist eine anonyme Funktion, die zwei Ganzzahlen aufnimmt und die Summe zurückgibt.

(x: Int, y: Int) => x + y

Der resultierende Ausdruck kann einem val zugewiesen werden:

val sum = (x: Int, y: Int) => x + y

Anonyme Funktionen werden hauptsächlich als Argumente für andere Funktionen verwendet. Beispielsweise erwartet die map Funktion in einer Sammlung eine andere Funktion als Argument:

// Returns Seq("FOO", "BAR", "QUX")
Seq("Foo", "Bar", "Qux").map((x: String) => x.toUpperCase)

Die Typen der Argumente der anonymen Funktion können weggelassen werden: Die Typen werden automatisch abgeleitet :

Seq("Foo", "Bar", "Qux").map((x) => x.toUpperCase)

Wenn es nur ein Argument gibt, können die Klammern um dieses Argument weggelassen werden:

Seq("Foo", "Bar", "Qux").map(x => x.toUpperCase)

Unterstreicht die Kurzschrift

Es gibt eine noch kürzere Syntax, für die keine Namen für die Argumente erforderlich sind. Das obige Snippet kann geschrieben werden:

Seq("Foo", "Bar", "Qux").map(_.toUpperCase)

_ stellvertretend für die anonymen Funktionsargumente. Bei einer anonymen Funktion mit mehreren Parametern verweist jedes Vorkommen von _ auf ein anderes Argument. Zum Beispiel sind die beiden folgenden Ausdrücke gleichwertig:

// Returns "FooBarQux" in both cases
Seq("Foo", "Bar", "Qux").reduce((s1, s2) => s1 + s2)
Seq("Foo", "Bar", "Qux").reduce(_ + _)

Bei Verwendung dieser Abkürzung kann jedes von positional _ dargestellte Argument nur einmal und in derselben Reihenfolge referenziert werden.

Anonyme Funktionen ohne Parameter

Lassen Sie die Parameterliste leer, um einen Wert für eine anonyme Funktion zu erstellen, für die keine Parameter verwendet werden.

val sayHello = () => println("hello")

Zusammensetzung

Die Funktionszusammenstellung ermöglicht es zwei Funktionen zu bedienen und als eine einzige Funktion betrachtet zu werden. Mathematisch ausgedrückt wird bei einer Funktion f(x) und einer Funktion g(x) die Funktion h(x) = f(g(x)) .

Wenn eine Funktion kompiliert wird, wird sie zu einem mit Function1 Typ kompiliert. Scala stellt in der Function1 Implementierung zwei Methoden für die Komposition andThen : andThen und compose . Die compose passt zu der obigen mathematischen Definition wie folgt:

val f: B => C = ...
val g: A => B = ...

val h: A => C = f compose g

Das andThen (denke, h(x) = g(f(x)) ) hat ein eher 'DSL-ähnliches' Gefühl:

val f: A => B = ...
val g: B => C = ...

val h: A => C = f andThen g

Eine neue anonyme Funktion wird zugewiesen, die über f und g . Diese Funktion ist in beiden Fällen an die neue Funktion h gebunden.

def andThen(g: B => C): A => C = new (A => C){
  def apply(x: A) = g(self(x))
}

Wenn entweder f oder g über einen Nebeneffekt wirkt, führt der Aufruf von h dazu, dass alle Nebeneffekte von f und g in der Reihenfolge auftreten. Gleiches gilt für alle veränderlichen Zustandsänderungen.

Beziehung zu PartialFunctions

trait PartialFunction[-A, +B] extends (A => B)

Jede PartialFunction mit einem Argument ist auch eine Function1 . Dies ist im formalen mathematischen Sinne kontraintuitiv, passt jedoch besser zu objektorientiertem Design. Aus diesem Grund muss Function1 keine konstante true isDefinedAt Methode isDefinedAt .

Um eine Teilfunktion (die auch eine Funktion ist) zu definieren, verwenden Sie folgende Syntax:

{ case i: Int => i + 1 } // or equivalently { case i: Int ⇒ i + 1 }

Weitere Informationen finden Sie unter PartialFunctions .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow