Scala Language
funktioner
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 .