Recherche…


Remarques

Scala s'efforce de traiter les méthodes et les fonctions de manière identique sur le plan syntaxique. Mais sous le capot, ce sont des concepts distincts.

Une méthode est un code exécutable et n'a aucune représentation de valeur.

Une fonction est une instance d'objet réelle de type Function1 (ou un type similaire d'une autre arité). Son code est contenu dans sa méthode d' apply . Effectivement, il agit simplement comme une valeur qui peut être transmise.

Incidemment, la capacité à traiter les fonctions comme des valeurs est exactement ce que l'on entend par un langage prenant en charge les fonctions d'ordre supérieur. Les instances de fonction sont l'approche de Scala pour implémenter cette fonctionnalité.

Une fonction réelle d'ordre supérieur est une fonction qui prend une valeur de fonction en tant qu'argument ou retourne une valeur de fonction. Mais dans Scala, comme toutes les opérations sont des méthodes, il est plus général de penser à des méthodes qui reçoivent ou renvoient des paramètres de fonction. Donc, la map , telle que définie sur Seq pourrait être considérée comme une "fonction d'ordre supérieur" en raison de son paramètre étant une fonction, mais ce n'est pas littéralement une fonction; c'est une méthode.

Utiliser des méthodes comme valeurs de fonction

Le compilateur Scala convertira automatiquement les méthodes en valeurs de fonction afin de les transmettre à des fonctions de niveau supérieur.

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

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

Dans l'exemple ci-dessus, MyObject.mapMethod n'est pas un appel de fonction, mais est transmis à map tant que valeur. En effet, la map nécessite une valeur de fonction qui lui est transmise, comme on peut le voir dans sa signature. La signature de la map d'une List[A] (une liste d'objets de type A ) est:

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

La partie f: (A) => B indique que le paramètre de cet appel de méthode est une fonction qui prend un objet de type A et retourne un objet de type B A et B sont définis arbitrairement. En revenant au premier exemple, nous pouvons voir que mapMethod prend un Int (qui correspond à A ) et renvoie une String (qui correspond à B ). Ainsi, mapMethod est une valeur de fonction valide à transmettre à la map . Nous pourrions réécrire le même code comme ceci:

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

Cela inscrit la valeur de la fonction, ce qui peut ajouter de la clarté aux fonctions simples.

Fonctions d'ordre élevé (fonction comme paramètre)

Une fonction d'ordre supérieur, par opposition à une fonction du premier ordre, peut prendre l'une des trois formes suivantes:

  • Un ou plusieurs de ses paramètres est une fonction et renvoie une valeur.

  • Il retourne une fonction, mais aucun de ses paramètres n'est une fonction.

  • Les deux ci-dessus: Un ou plusieurs de ses paramètres est une fonction, et il retourne une fonction.

    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
        }
    

Ici, la fonction map prend comme paramètre une fonction getFullName(n._1,n._2) . Cela s'appelle HOF (Fonction d'ordre supérieur).

Arguments évaluation paresseuse

Scala prend en charge l'évaluation paresseuse des arguments de fonction en utilisant la notation: def func(arg: => String) . Un tel argument de fonction peut prendre un objet String régulier ou une fonction d'ordre supérieur avec le type de retour String . Dans le second cas, l'argument de fonction serait évalué sur l'accès aux valeurs.

S'il vous plaît voir l'exemple:

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 appel de smartMediator renvoie la valeur None et imprime le message "Applying mediator" .

dumbMediator appel dumbMediator renvoie la valeur None et imprime le message "Calculating expensive data! Applying mediator" .

L'évaluation différée peut être extrêmement utile lorsque vous souhaitez optimiser un calcul d'arguments coûteux.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow