Zoeken…


Opmerkingen

Scala doet er alles aan om methoden en functies als syntactisch identiek te behandelen. Maar onder de motorkap zijn het verschillende concepten.

Een methode is uitvoerbare code en heeft geen waardepresentatie.

Een functie is een werkelijke objectinstantie van het type Function1 (of een vergelijkbaar type van een andere arity). De code is opgenomen in de methode van apply . In feite fungeert het gewoon als een waarde die kan worden doorgegeven.

Overigens is de mogelijkheid behandelen functioneert als waarden wat wordt bedoeld met een taal met ondersteuning voor hogere orde functies. Functie-instanties zijn Scala's benadering van het implementeren van deze functie.

Een werkelijke functie van hogere orde is een functie die een functiewaarde als argument neemt of een functiewaarde retourneert. Maar in Scala, omdat alle bewerkingen methoden zijn, is het algemener om te denken aan methoden die functieparameters ontvangen of retourneren. Dus map , zoals gedefinieerd op Seq kan worden gezien als een "hogere orde functie" vanwege de parameter die een functie is, maar het is niet letterlijk een functie; het is een methode.

Methoden gebruiken als functiewaarden

De Scala-compiler converteert methoden automatisch naar functiewaarden om ze door te geven aan functies van een hogere orde.

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

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

In het bovenstaande voorbeeld is MyObject.mapMethod geen functieaanroep, maar in plaats daarvan doorgegeven aan map als een waarde. Inderdaad, map vereist een functie waarde die eraan is doorgegeven, zoals te zien is in zijn handtekening. De handtekening voor de map van een List[A] (een lijst met objecten van type A ) is:

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

Het gedeelte f: (A) => B geeft aan dat de parameter voor deze methode-aanroep een functie is die een object van type A en een object van type B retourneert. A en B zijn willekeurig gedefinieerd. Terugkerend naar het eerste voorbeeld, kunnen we zien dat mapMethod een Int (die overeenkomt met A ) en een String retourneert (die overeenkomt met B ). Zo is mapMethod een geldige functiewaarde die aan map moet worden doorgegeven. We kunnen dezelfde code als volgt herschrijven:

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

Dit onderstreept de functiewaarde, wat duidelijkheid kan toevoegen voor eenvoudige functies.

Hoge orderfuncties (functie als parameter)

Een hogere-orde functie, in tegenstelling tot een eerste-orde functie, kan een van drie vormen hebben:

  • Een of meer van zijn parameters is een functie en geeft een waarde terug.

  • Het retourneert een functie, maar geen van de parameters is een functie.

  • Beide bovenstaande: een of meer van zijn parameters is een functie en retourneert een functie.

    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
        }
    

Hier neemt de getFullName(n._1,n._2) de functie getFullName(n._1,n._2) als parameter. Dit wordt HOF (hogere orde functie) genoemd.

Argumenten luie evaluatie

Scala ondersteunt luie evaluatie voor functieargumenten met behulp van notatie: def func(arg: => String) . Een dergelijk functieargument kan een normaal String object of een hogere orde-functie met String retourtype aannemen. In het tweede geval zou het functieargument worden geëvalueerd op waardetoegang.

Zie het voorbeeld:

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 oproep zou geen waarde retourneren en het bericht "Applying mediator" afdrukken.

dumbMediator oproep zou geen waarde retourneren en het bericht "Calculating expensive data! Applying mediator" afdrukken.

Luie evaluatie kan zeer nuttig zijn wanneer u een overhead van dure argumentenberekening wilt optimaliseren.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow