Zoeken…


Opmerkingen

Scala heeft eersteklas functies.

Verschil tussen functies en methoden:

Een functie is geen methode in Scala: functies zijn een waarde en kunnen als zodanig worden toegewezen. Methoden (gemaakt met def ) moeten daarentegen tot een klasse, eigenschap of object behoren.

  • Functies worden gecompileerd tot een klasse die een eigenschap (zoals Function1 ) tijdens het compileren uitbreidt, en worden tijdens runtime geconstateerd naar een waarde. Methoden zijn daarentegen lid van hun klasse, eigenschap of object en bestaan daarbuiten niet.
  • Een methode kan worden geconverteerd naar een functie, maar een functie kan niet worden geconverteerd naar een methode.
  • Methoden kunnen typeparameterisatie hebben, functies niet.
  • Methoden kunnen standaardparameterwaarden hebben, functies niet.

Anonieme functies

Anonieme functies zijn functies die zijn gedefinieerd maar waaraan geen naam is toegewezen.

Het volgende is een anonieme functie die twee gehele getallen opneemt en de som retourneert.

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

De resulterende uitdrukking kan worden toegewezen aan een val :

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

Anonieme functies worden voornamelijk gebruikt als argumenten voor andere functies. Bijvoorbeeld, de map -functie op een verzameling verwacht dat een andere functie als argument:

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

De typen argumenten van de anonieme functie kunnen worden weggelaten: de typen worden automatisch afgeleid :

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

Als er slechts één argument is, kunnen de haakjes rond dat argument worden weggelaten:

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

Onderstreept stenografie

Er is een nog kortere syntaxis waarvoor geen namen nodig zijn voor de argumenten. Het bovenstaande fragment kan worden geschreven:

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

_ vertegenwoordigt de anonieme functieargumenten positioneel. Met een anonieme functie die meerdere parameters heeft, verwijst elk voorkomen van _ naar een ander argument. De twee volgende uitdrukkingen zijn bijvoorbeeld equivalent:

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

Wanneer u deze steno gebruikt, kan naar elk argument dat wordt voorgesteld door de positionele _ slechts één keer worden verwezen en in dezelfde volgorde.

Anonieme functies zonder parameters

Om een waarde te creëren voor een anonieme functie waarvoor geen parameters nodig zijn, laat u de parameterlijst leeg:

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

Samenstelling

Met de functiesamenstelling kunnen twee functies werken en worden gezien als een enkele functie. In wiskundige termen uitgedrukt, gegeven een functie f(x) en een functie g(x) , de functie h(x) = f(g(x)) .

Wanneer een functie wordt gecompileerd, wordt deze gecompileerd tot een type dat is gerelateerd aan Function1 . Scala biedt twee methoden in de Function1 implementatie met betrekking tot compositie: andThen en compose . De compose methode past als volgt bij de bovenstaande wiskundige definitie:

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

val h: A => C = f compose g

De andThen (denk h(x) = g(f(x)) ) heeft een meer 'DSL-achtig' gevoel:

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

val h: A => C = f andThen g

Er wordt een nieuwe anonieme functie toegewezen die is gesloten voor f en g . Deze functie is in beide gevallen gebonden aan de nieuwe functie h .

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

Als f of g via een bijwerking werkt, dan roept het aanroepen van h alle bijwerkingen van f en g in de volgorde. Hetzelfde geldt voor eventuele veranderlijke statusveranderingen.

Relatie met gedeeltelijke functies

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

Elke single-argument PartialFunction is ook een Function1 . Dit is contra-intuïtief in formele wiskundige zin, maar past beter bij objectgeoriënteerd ontwerp. Om deze reden hoeft Function1 geen constante true isDefinedAt methode te bieden.

Gebruik de volgende syntaxis om een gedeeltelijke functie (die ook een functie is) te definiëren:

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

Kijk voor meer informatie op PartialFunctions .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow