59 votes

Neuf façons de définir une méthode dans Scala?

J'ai donc essayé de puzzle à travers les différentes façons dont vous pouvez définir des trucs en Scala, compliquée par mon manque de compréhension de la façon dont {} des blocs sont traités:

object NewMain extends Thing{

    def f1 = 10
    def f2 {10}
    def f3 = {10}
    def f4() = 10
    def f5() {10}
    def f6() = {10}
    def f7 = () => 10
    def f8 = () => {10}
    def f9 = {() => {10}}

    def main(args: Array[String]){
        println(f1)     // 10
        println(f2)     // ()
        println(f3)     // 10
        println(f4)     // 10
        println(f4())   // 10
        println(f5)     // ()
        println(f5())   // ()
        println(f6)     // 10
        println(f6())   // 10
        println(f7)     // <function0>
        println(f7())   // 10
        println(f8)     // <function0>
        println(f8())   // 10
        println(f9)     // <function0>
        println(f9())   // 10
    }

}

On peut supposer que certaines de ces équivalents, certains de ces sommes sucre syntaxique pour d'autres, et certains sont des choses que je ne devrais pas utiliser, mais je ne peux pas pour la vie de me comprendre. Mes questions spécifiques:

  • Comment est-ce que println(f2) et println(f5()) donne unit? N'est pas le dernier élément dans le bloc 10? Comment est-il différent de println(f3()), ce qui donne 10?

  • Si println(f5) donne unit, ne devriez - println(f5()) non valide, car unit n'est pas une fonction? La même chose s'applique println(f6) et println(f6())

  • De tous ceux qui imprimer 10: f1, f3, f4, f4(), f6, f6(), f7(), f8(), f9(), est-il une différence fonctionnelle entre eux (en termes de ce qu'elle fait) ou l'utilisation des différences (en termes de quand je devrais utiliser qui)? Ou sont-ils tous équivalents?

32voto

nonVirtualThunk Points 2254

Pour répondre à vos questions dans l'ordre:

  • f2 et f5() rendement Unit car scala prend tout def sans un "=" à une fonction qui retourne Unit, indépendamment de ce que le dernier élément d'un bloc. C'est une bonne chose, car sinon il ne serait pas assez bavard pour définir une fonction qui ne retourne rien.
  • println(f5()) est valide, même si elle renvoie Unit parce que dans scala Unit est un objet valide, certes pas, vous pouvez instancier. Unit.toString() est valable, si ce n'est en général utile, l'état, par exemple.
  • Pas toutes les versions imprimer 10 sont les mêmes. Le plus important, f7,f8, et f9 sont en fait des fonctions qui retournent des fonctions qui retournent 10, plutôt que de retourner 10 directement. Lorsque vous déclarez def f8 = () => {10}, de déclarer une fonction f8 qui ne prend pas d'argument et retourne une fonction qui ne prend pas d'arguments et retourne un entier. Lorsque vous appelez println(f8) alors f8 dilligently retourne cette fonction pour vous. Lorsque vous appelez println(f8()) il renvoie la fonction, puis immédiatement à l'invoque.
  • Les fonctions f1,f3,f4, et f6 sont essentiellement équivalents en termes de ce qu'ils font, ils varient seulement en termes de style.

En tant que "utilisateur inconnu" indique, les accolades sont seulement important pour les fins de la détermination de la portée et de ne pas faire toute la différence dans votre cas d'utilisation ici.

17voto

SpiderPig Points 2126
def f() {...}

est sytactic de sucre pour

def f(): Unit = {...}

Donc, si vous omettez le "=", la méthode retournera toujours un objet de type Unit. En Scala, les méthodes et les expressions renvoient toujours quelque chose.

def f() = 10
is sytactic sugar for
def f() = {
10
}

Si vous écrivez def f() = () => 10, c'est la même que l'écriture de

def f() = {
() => 10
}

Cela signifie donc que f est de retourner un objet de fonction. Vous pouvez, toutefois, écrire

val f = () => 10

Lorsque vous l'appelez avec f (), elle renvoie 10 La fonction des objets et des méthodes peuvent être utilisées interchangingly dans la plupart des cas, mais il ya quelques différences syntaxiques. par exemple Lorsque vous écrivez

def f() = 10
println(f)

vous obtenez "10", mais quand vous écrivez

val f = () => 10
println(f)

vous obtenez

<function0>

D'autre part, si vous avez ce

val list = List(1,2,3)
def inc(x: Int) = x+1
val inc2 = (x: Int) => x+1
println(list.map(inc))
println(list.map(inc2))

Les deux println impression sera la même chose

List(2,3,4)

Lorsque vous utilisez le nom d'une méthode à un endroit où un objet de fonction est prévue et la signature de la méthode correspond à la signature de la fonction de l'objet, il est automatiquement converti. Donc, list.map(inc) est automatiquement converti par le compilateur scala en

list.map(x => inc(x))

4voto

user unknown Points 15555
def f1 = 10    
def f2 {10}    

Le deuxième formulaire ne permet pas d'utiliser une assignation. Par conséquent, vous pouvez la considérer comme une Procédure. Il n'est pas destiné à retourner quelque chose, et renvoie donc à l'Unité, même si la dernière instruction pourrait être utilisée pour renvoyer quelque chose de précis (mais il pourrait être un if, qui ne serait que quelque chose de spécifique à une branche).

def f1 = 10    
def f3 = {10}  

Vous n'avez pas besoin d'accolades ici. Vous en avez besoin, par exemple, si vous définissez un val, de sorte que le champ d'application de ce val est limitée à l'affichage de bloc.

def sqrGtX (n:Int, x: Int) = {
  val sqr = n * n
  if (sqr > x) 
    sqr / 2 
  else x / 2 
}  

Vous avez besoin des accolades pour définir val sqr ici. Si le val est déclaré dans un intérieur de la branche, les accolades n'avez pas besoin d'être au top-niveau de la méthode:

def foo (n:Int, x: Int) = 
  if (n > x) {
    val bar = x * x + n * n
    println (bar) 
    bar - 2  
  } else x - 2 

Pour complément d'enquête lorsque les deux méthodes donnent le même résultat, vous pouvez les compiler et comparer le bytecode. Deux binaires identiques méthodes seront identiques.

Prograide.com

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.

Powered by:

X