Sök…


Anmärkningar

Scala har förstklassiga funktioner.

Skillnad mellan funktioner och metoder:

En funktion är inte en metod i Scala: funktioner är ett värde och kan tilldelas som sådana. Metoder (skapade med def ) måste å andra sidan tillhöra en klass, drag eller objekt.

  • Funktioner sammanställs till en klass som utökar ett drag (t.ex. Function1 ) vid kompileringstid och instanseras till ett värde vid körning. Metoder å andra sidan är medlemmar i deras klass, drag eller objekt och finns inte utanför det.
  • En metod kan konverteras till en funktion, men en funktion kan inte konverteras till en metod.
  • Metoder kan ha typparametrering, medan funktioner inte gör det.
  • Metoder kan ha standardvärden för parametrar, medan funktioner inte kan.

Anonyma funktioner

Anonyma funktioner är funktioner som definieras men inte tilldelas ett namn.

Följande är en anonym funktion som tar in två heltal och returnerar summan.

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

Det resulterande uttrycket kan tilldelas en val :

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

Anonyma funktioner används främst som argument till andra funktioner. Till exempel map förväntar funktion på en samling annan funktion som dess argument:

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

Typerna av argumenten för den anonyma funktionen kan utelämnas: typerna utgår automatiskt :

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

Om det bara finns ett argument kan parenteserna runt det argumentet utelämnas:

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

Underkorsade korthet

Det finns en ännu kortare syntax som inte kräver namn för argumenten. Ovanstående kod kan skrivas:

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

_ representerar de anonyma funktionsargumenten positivt. Med en anonym funktion som har flera parametrar hänvisar varje förekomst av _ till ett annat argument. Till exempel är de två följande uttryck likvärdiga:

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

När du använder denna korthandling kan alla argument som representeras av positionen _ bara refereras en gång och i samma ordning.

Anonyma funktioner utan parametrar

Om du vill skapa ett värde för en anonym funktion som inte tar parametrar lämnar du parameterlistan tom:

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

Sammansättning

Funktionssammansättning gör det möjligt för två funktioner att fungera och ses som en enda funktion. Uttryckt i matematiska termer, ges en funktion f(x) och en funktion g(x) , funktionen h(x) = f(g(x)) .

När en funktion kompileras kompileras den till en typ relaterad till Function1 . Scala tillhandahåller två metoder i implementering av Function1 relaterade till sammansättning: och andThen och compose . compose passar sålunda med ovanstående matematiska definition:

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

val h: A => C = f compose g

andThen (tror h(x) = g(f(x)) ) har en mer "DSL-liknande" känsla:

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

val h: A => C = f andThen g

En ny anonym funktion tilldelas med den som är stängd över f och g . Denna funktion är bunden till den nya funktionen h i båda fallen.

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

Om antingen f eller g fungerar via en bieffekt, kommer att ringa h att orsaka alla biverkningar av f och g att ske i ordningen. Detsamma gäller för eventuella förändringslägen förändringar.

Förhållande till partiella funktioner

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

Varje enskilt argument PartialFunction är också en Function1 . Detta är motintuitivt i formell matematisk mening, men passar bättre objektorienterad design. Av denna anledning behöver Function1 inte tillhandahålla en konstant true isDefinedAt metod.

För att definiera en partiell funktion (som också är en funktion) använder du följande syntax:

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

För mer information, ta en titt på PartialFunctions .



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow