Ricerca…


Osservazioni

Scala ha funzioni di prima classe.

Differenza tra funzioni e metodi:

Una funzione non è un metodo in Scala: le funzioni sono un valore e possono essere assegnate come tali. I metodi (creati usando def ), d'altra parte, devono appartenere a una classe, un tratto o un oggetto.

  • Le funzioni sono compilate in una classe che estende un tratto (come Function1 ) in fase di compilazione e sono istanziate a un valore in fase di esecuzione. I metodi, d'altra parte, sono membri della loro classe, tratto o oggetto e non esistono al di fuori di questo.
  • Un metodo può essere convertito in una funzione, ma una funzione non può essere convertita in un metodo.
  • I metodi possono avere la parametrizzazione dei tipi, mentre le funzioni no.
  • I metodi possono avere valori di default dei parametri, mentre le funzioni no.

Funzioni anonime

Le funzioni anonime sono funzioni definite ma non assegnate a un nome.

La seguente è una funzione anonima che accetta due interi e restituisce la somma.

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

L'espressione risultante può essere assegnata a un val :

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

Le funzioni anonime vengono principalmente utilizzate come argomenti per altre funzioni. Ad esempio, la funzione map su una raccolta prevede un'altra funzione come argomento:

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

I tipi di argomenti della funzione anonima possono essere omessi: i tipi vengono dedotti automaticamente :

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

Se c'è un solo argomento, le parentesi attorno a quell'argomento possono essere omesse:

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

Sottolinea la stenografia

C'è una sintassi ancora più breve che non richiede nomi per gli argomenti. Lo snippet sopra riportato può essere scritto:

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

_ rappresenta gli argomenti della funzione anonima in modo posizionale. Con una funzione anonima che ha più parametri, ogni occorrenza di _ farà riferimento a un argomento diverso. Ad esempio, le due espressioni seguenti sono equivalenti:

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

Quando si utilizza questa stenografia, qualsiasi argomento rappresentato da _ posizionale può essere fatto riferimento una sola volta e nello stesso ordine.

Funzioni anonime senza parametri

Per creare un valore per una funzione anonima che non accetta parametri, lascia vuoto l'elenco dei parametri:

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

Composizione

La composizione delle funzioni consente di far funzionare due funzioni e di essere viste come una singola funzione. Espresso in termini matematici, data una funzione f(x) e una funzione g(x) , la funzione h(x) = f(g(x)) .

Quando una funzione viene compilata, viene compilata su un tipo correlato a Function1 . Scala fornisce due metodi nell'implementazione Function1 relativa alla composizione: andThen e compose . Il metodo di compose adatta alla definizione matematica di cui sopra in questo modo:

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

val h: A => C = f compose g

The andThen (penso che h(x) = g(f(x)) ) abbia un sentimento più simile a 'DSL':

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

val h: A => C = f andThen g

Una nuova funzione anonima viene allocato con che è chiuso su f e g . Questa funzione è associata alla nuova funzione h in entrambi i casi.

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

Se uno dei due f o g funziona tramite un effetto collaterale, quindi chiamando h causerà tutti gli effetti collaterali di f e g per accadere nell'ordine. Lo stesso vale per qualsiasi cambiamento di stato mutabile.

Relazione con le funzioni parziali

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

Ogni singola funzione PartialFunction è anche una Function1 . Questo è contro-intuitivo in senso matematico formale, ma si adatta meglio alla progettazione orientata agli oggetti. Per questo motivo Function1 non deve fornire un metodo isDefinedAt true isDefinedAt .

Per definire una funzione parziale (che è anche una funzione), utilizzare la seguente sintassi:

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

Per ulteriori dettagli, dare un'occhiata a PartialFunctions .



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow