I matematici hanno i loro piccoli modi divertenti, quindi invece di dire "allora chiamiamo funzione f
passandola x
come parametro", come direbbero i programmatori, parlano di "applicare la funzione f
al suo argomento x
".
In matematica e informatica, Apply è una funzione che applica funzioni agli argomenti.
Wikipedia
apply
serve allo scopo di colmare il divario tra paradigmi orientati agli oggetti e funzionali in Scala. Ogni funzione in Scala può essere rappresentata come un oggetto. Ogni funzione ha anche un tipo OO: ad esempio, una funzione che accetta un Int
parametro e restituisce un Int
tipo OO avrà Function1[Int,Int]
.
// define a function in scala
(x:Int) => x + 1
// assign an object representing the function to a variable
val f = (x:Int) => x + 1
Dato che tutto è un oggetto in Scala f
ora può essere trattato come un riferimento Function1[Int,Int]
all'oggetto. Ad esempio, possiamo chiamare il toString
metodo ereditato da Any
, che sarebbe stato impossibile per una funzione pura, perché le funzioni non hanno metodi:
f.toString
Oppure potremmo definire un altro Function1[Int,Int]
oggetto chiamando il compose
metodo f
e concatenando due diverse funzioni insieme:
val f2 = f.compose((x:Int) => x - 1)
Ora se vogliamo effettivamente eseguire la funzione, o come dice il matematico "applica una funzione ai suoi argomenti", chiameremmo il apply
metodo Function1[Int,Int]
sull'oggetto:
f2.apply(2)
Scrivere f.apply(args)
ogni volta che si desidera eseguire una funzione rappresentata come oggetto è orientato agli oggetti, ma aggiungerebbe un sacco di disordine al codice senza aggiungere molte informazioni aggiuntive e sarebbe bello poter usare più notazioni standard, come come f(args)
. È qui che interviene il compilatore Scala e ogni volta che abbiamo un riferimento f
a un oggetto funzione e scriviamo f (args)
per applicare argomenti alla funzione rappresentata, il compilatore si espande silenziosamente f (args)
alla chiamata del metodo oggetto f.apply (args)
.
Ogni funzione in Scala può essere trattata come un oggetto e funziona anche nell'altro modo - ogni oggetto può essere trattato come una funzione, purché abbia il apply
metodo. Tali oggetti possono essere utilizzati nella notazione della funzione:
// we will be able to use this object as a function, as well as an object
object Foo {
var y = 5
def apply (x: Int) = x + y
}
Foo (1) // using Foo object in function notation
Ci sono molti casi d'uso in cui vorremmo trattare un oggetto come una funzione. Lo scenario più comune è un modello di fabbrica . Invece di aggiungere disordine al codice utilizzando un metodo factory, possiamo apply
obiettare a una serie di argomenti per creare una nuova istanza di una classe associata:
List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation
// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3)
Quindi il apply
metodo è solo un modo pratico per colmare il divario tra funzioni e oggetti in Scala.