Ricerca…


Osservazioni

Scala fa di tutto per trattare i metodi e le funzioni in modo sintatticamente identico. Ma sotto il cofano, sono concetti distinti.

Un metodo è codice eseguibile e non ha alcuna rappresentazione di valore.

Una funzione è un'istanza di oggetto reale di tipo Function1 (o un tipo simile di un'altra arity). Il suo codice è contenuto nel suo metodo di apply . Effettivamente, agisce semplicemente come un valore che può essere passato in giro.

Per inciso, la capacità di trattare le funzioni come valori è esattamente ciò che si intende per linguaggio che supporta le funzioni di ordine superiore. Le istanze di funzione sono l'approccio di Scala all'implementazione di questa funzione.

Una funzione reale di ordine superiore è una funzione che accetta un valore di funzione come argomento o restituisce un valore di funzione. Ma in Scala, poiché tutte le operazioni sono metodi, è più generale pensare a metodi che ricevono o restituiscono parametri di funzione. Quindi la map , come definita in Seq potrebbe essere pensata come una "funzione di ordine superiore" a causa del fatto che il suo parametro è una funzione, ma non è letteralmente una funzione; è un metodo.

Utilizzo dei metodi come valori di funzione

Il compilatore Scala convertirà automaticamente i metodi in valori di funzione allo scopo di passarli in funzioni di ordine superiore.

object MyObject {
  def mapMethod(input: Int): String = {
    int.toString
  }
}

Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")

Nell'esempio sopra, MyObject.mapMethod non è una chiamata di funzione, ma viene invece passata alla map come valore. Infatti, la map richiede un valore di funzione passato ad esso, come si può vedere nella sua firma. La firma per la map di un List[A] (un elenco di oggetti di tipo A ) è:

def map[B](f: (A) ⇒ B): List[B]

La parte f: (A) => B indica che il parametro per questa chiamata di metodo è una funzione che accetta un oggetto di tipo A e restituisce un oggetto di tipo B A e B sono definiti arbitrariamente. Tornando al primo esempio, possiamo vedere che mapMethod accetta un Int (che corrisponde ad A ) e restituisce una String (che corrisponde a B ). Quindi mapMethod è un valore di funzione valido per passare alla map . Potremmo riscrivere lo stesso codice come questo:

Seq(1, 2, 3).map(x:Int => int.toString)

Questo inline il valore della funzione, che può aggiungere chiarezza per le funzioni semplici.

Funzioni di ordine elevato (funzione come parametro)

Una funzione di ordine superiore, al contrario di una funzione di primo ordine, può avere una delle tre forme:

  • Uno o più dei suoi parametri è una funzione e restituisce un valore.

  • Restituisce una funzione, ma nessuno dei suoi parametri è una funzione.

  • Entrambi i precedenti: uno o più dei suoi parametri è una funzione e restituisce una funzione.

    object HOF {
        def main(args: Array[String]) {
        val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s"))
        //HOF
         val fullNameList= list.map(n => getFullName(n._1, n._2))
    
         }
    
        def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName
        }
    

Qui la funzione mappa assume come parametri un parametro getFullName(n._1,n._2) . Questo è chiamato HOF (funzione di ordine superiore).

Argomenti valutazione pigra

Scala supporta la valutazione lazy per gli argomenti delle funzioni usando notazione: def func(arg: => String) . Tale argomento di funzione potrebbe richiedere un oggetto String regolare o una funzione di ordine superiore con tipo di restituzione String . Nel secondo caso, l'argomento della funzione verrebbe valutato sull'accesso valore.

Si prega di vedere l'esempio:

def calculateData: String = {
  print("Calculating expensive data! ")
  "some expensive data"
}

def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
  print("Applying mediator")
  preconditions match {
    case true => Some(data)
    case false => None
  }
}

def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
  print("Applying mediator")
  preconditions match {
    case true => Some(data)
    case false => None
  }
}

smartMediator(preconditions = false, calculateData)

dumbMediator(preconditions = false, calculateData)

smartMediator chiamata smartMediator restituirà None value e stamperà il messaggio "Applying mediator" .

dumbMediator chiamata dumbMediator restituirebbe Nessun valore e stamperà il messaggio "Calculating expensive data! Applying mediator" .

La valutazione pigra potrebbe essere estremamente utile quando si desidera ottimizzare un sovraccarico di costosi calcoli di argomenti.



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