J'ai lu Scala Functions (partie d'une autre tournée de Scala ). Dans ce post, il a déclaré:
Les méthodes et les fonctions ne sont pas la même chose
Mais il n'a rien expliqué à ce sujet. Qu'est-ce qu'il essayait de dire?
J'ai lu Scala Functions (partie d'une autre tournée de Scala ). Dans ce post, il a déclaré:
Les méthodes et les fonctions ne sont pas la même chose
Mais il n'a rien expliqué à ce sujet. Qu'est-ce qu'il essayait de dire?
Jim a eu ce assez bien couvert dans son billet de blog, mais je vais poster un briefing ici pour référence.
Tout d'abord, voyons ce que la Scala de Spécification de nous le dire. Le chapitre 3 (types) de nous dire à propos des Types de Fonction (3.2.9) et les Types de Méthode (3.3.1). Le chapitre 4 (la base de déclarations) parle de la Déclaration de la Valeur et des Définitions (4.1), la Déclaration de la Variable et Définitions (4.2) et les Fonctions Déclarations et les Définitions (4.6). Le chapitre 6 (expressions) parle de Fonctions Anonymes (6.23) et la Méthode des Valeurs de (6.7). Curieusement, les valeurs de la fonction est parlé une fois sur 3.2.9, et pas ailleurs.
Un Type de Fonction est (en gros) un type de la forme (T1, ..., Tn) => U, qui est une abréviation pour le caractère FunctionN
dans la bibliothèque standard. Les Fonctions anonymes et Méthode les Valeurs ont la fonction des types et des types de fonction peut être utilisé comme une partie de la valeur de la variable et la fonction déclarations et les définitions. En fait, il peut être une partie d'un type de méthode.
Un Type de Méthode est un non-type de la valeur. Cela signifie qu'il est sans valeur - aucun objet, aucune instance n' - avec un type de méthode. Comme mentionné ci-dessus, une Méthode de la Valeur a un Type de Fonction. Un type de méthode est une def
déclaration - tout sur un def
à l'exception de son corps.
Les Déclarations de valeur et les Définitions et les Déclarations de Variables et Définitions sont val
et var
des déclarations, y compris à la fois le type et la valeur - qui peut être, respectivement, en Fonction du Type et de Fonctions Anonymes ou de la Méthode des Valeurs. Notez que, sur la JVM, ces (méthode de valeurs) sont mis en œuvre avec ce que Java appelle "méthodes".
Une Déclaration de Fonction est un def
déclaration, y compris le type et le corps. Le type de partie est le Type de Méthode, et le corps est une expression ou d'un bloc. C'est également mise en œuvre sur la JVM avec ce que Java appelle "méthodes".
Enfin, une Fonction Anonyme est une instance d'un Type de Fonction (c'est à dire une instance de la trait FunctionN
), et une Méthode de la Valeur est la même chose! La distinction est que la Méthode de la Valeur est créée à partir de méthodes, soit par postfixing un trait de soulignement (m _
est une méthode de la valeur correspondant à la "déclaration de fonction" (def
) m
), ou par un processus appelé eta-extension, qui est comme une automatique en fonte à partir de la méthode de la fonction.
C'est ce que les spécifications dire, permettez-moi de mettre cela en place-avant: nous n'utilisons pas ce vocabulaire! Elle conduit à trop de confusion entre les soi-disant "déclaration de fonction", qui est une partie du programme (chapitre 4 -- base des déclarations) et "fonction anonyme", qui est une expression, et "type de fonction", qui est, un type -- un trait.
La terminologie ci-dessous, et utilisé par des Scala programmeurs, fait un changement de la terminologie du cahier des charges: au lieu de dire une déclaration de fonction, nous disons méthode. Ou même de la déclaration de la méthode. Nous notons en outre que les déclarations de valeur et les déclarations de variables sont également des méthodes pour des raisons pratiques.
Donc, compte tenu de la modification ci-dessus dans la terminologie, voici une explication pratique de la distinction.
Une fonction est un objet qui contient l'un de l' FunctionX
traits, tels que l' Function0
, Function1
, Function2
, etc. Il peut être notamment PartialFunction
, ce qui s'étend Function1
.
Nous allons voir le type de signature pour l'un de ces traits:
trait Function2[-T1, -T2, +R] extends AnyRef
Ce trait a une méthode abstraite (il a quelques méthodes concrètes en tant que bien):
def apply(v1: T1, v2: T2): R
Et que nous disent tous qu'il y a à savoir sur le sujet. Une fonction a un apply
méthode qui reçoit les N paramètres de types T1, T2, ..., TN, et renvoie à quelque chose de type R
. Il est contre-variante sur les paramètres qu'il reçoit, et co-variante sur le résultat.
La variance signifie qu'un Function1[Seq[T], String]
est un sous-type d' Function1[List[T], AnyRef]
. Étant un sous-type signifie qu'il peut être utilisé à la place de . On peut facilement voir que si je vais l'appeler f(List(1, 2, 3))
et s'attendre à un AnyRef
de retour, l'un des deux types ci-dessus serait de travailler.
Maintenant, quelle est la similitude d'une méthode et d'une fonction? Eh bien, si f
est une fonction et m
est une méthode locale de la portée, alors que les deux peuvent être appelés comme ceci:
val o1 = f(List(1, 2, 3))
val o2 = m(List(1, 2, 3))
Ces appels sont en fait différents, parce que le premier est juste un sucre syntaxique. Scala augmente à:
val o1 = f.apply(List(1, 2, 3))
Ce qui, bien sûr, est un appel de méthode sur l'objet" f
. Les fonctions ont également d'autres sucres syntaxiques à son avantage: la fonction littéraux (deux d'entre eux, en fait) et (T1, T2) => R
type de signatures. Par exemple:
val f = (l: List[Int]) => l mkString ""
val g: (AnyVal) => String = {
case i: Int => "Int"
case d: Double => "Double"
case o => "Other"
}
Une autre similitude entre une méthode et une fonction, c'est que l'ancien peut être facilement convertie en celle-ci:
val f = m _
Scala étendra que, en supposant m
type (List[Int])AnyRef
(Scala 2.7):
val f = new AnyRef with Function1[List[Int], AnyRef] {
def apply(x$1: List[Int]) = this.m(x$1)
}
Sur Scala 2.8, il utilise un AbstractFunction1
classe de réduire la taille des classes.
D'avis que l'on ne peut pas convertir dans l'autre sens -- à partir d'une fonction à une méthode.
Méthodes, cependant, ont un grand avantage (enfin, deux, ils peuvent être un peu plus rapide): ils peuvent recevoir des paramètres de type. Par exemple, f
ci-dessus peuvent nécessairement spécifier le type d' List
il reçoit (List[Int]
dans l'exemple), m
pouvez paramétrer:
def m[T](l: List[T]): String = l mkString ""
Je pense que cela couvre à peu près tout, mais je vais être heureux de compléter cela avec des réponses à toutes les questions qui peuvent rester.
Une grande différence pratique entre une méthode et une fonction est ce que return
signifie. return
ne renvoie jamais qu'une méthode. Par exemple:
scala> val f = () => { return "test" }
<console>:4: error: return outside method definition
val f = () => { return "test" }
^
Le retour d'une fonction définie dans une méthode effectue un retour non local:
scala> def f: String = {
| val g = () => { return "test" }
| g()
| "not this"
| }
f: String
scala> f
res4: String = test
Considérant que le retour d'une méthode locale ne renvoie que de cette méthode.
scala> def f2: String = {
| def g(): String = { return "test" }
| g()
| "is this"
| }
f2: String
scala> f2
res5: String = is this
fonction Une fonction peut être appelée avec une liste d'arguments pour produire un résultat. Une fonction est une liste de paramètres, d'un corps et d'un type de résultat. Les fonctions membres d'une classe, d'un trait de caractère, ou un objet singleton sont appelées méthodes. Fonctions définies à l'intérieur d'autres fonctions sont appelées les fonctions locales. Fonctions avec le type de résultat de l'Unité sont appelés les procédures. Les fonctions anonymes dans le code source sont appelés des littéraux de fonction. Au moment de l'exécution, en fonction des littéraux sont instanciés dans des objets appelés les valeurs de la fonction.
La programmation Scala Deuxième Édition. Martin Odersky - Lex Cuillère - Bill Venners
Disons que vous avez une Liste
scala> val x =List.range(10,20)
x: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
Définir une Méthode
scala> def m1(i:Int)=i+2
m1: (i: Int)Int
Définir une Fonction
scala> (i:Int)=>i+2
res0: Int => Int = <function1>
scala> x.map((x)=>x+2)
res2: List[Int] = List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
Méthode D'Accepter L'Argument
scala> m1(2)
res3: Int = 4
La définition de Fonction avec val
scala> val p =(i:Int)=>i+2
p: Int => Int = <function1>
Argumnet de fonction est Facultative
scala> p(2)
res4: Int = 4
scala> p
res5: Int => Int = <function1>
Argument à la Méthode est Mandoatory
scala> m1
<console>:9: error: missing arguments for method m1;
follow this method with `_' if you want to treat it as a partially applied function
Vérifiez les points suivants Tutoriel qui explique en passant les différences avec les autres exemples comme autre exemple de diff avec la Méthode Vs Fonction à l'Aide de la fonction en tant que Variables, la création de la fonction que la fonction renvoyée
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.