2012-11-16 3 views
0

Il y a un exemple dans "Scala in Depth" où l'auteur explique comment scala peut faire un certain niveau d'inférence sur les arguments passés dans les méthodes. A titre d'exemple, le suivant est affiché:"Les types utilisés dans une fonction sont des littéraux"?

def myMethod(functionLiteral: A => B):Unit 
myMethod({ arg:A => new B}) 
myMethod({ arg => new B}) 

Juste pour savoir ce que l'auteur parle, je fais ce qui suit dans le REPL:

def myMethod(functionLiteral: Boolean => Boolean):Unit = {} 
myMethod({a:Boolean => true}) 
myMethod({a => true}) 

La seule chose révélatrice qui se passe ici est que le compilateur ne lance pas d'erreur.

L'auteur essaie-t-il de dire que l'argument de fonction a est supposé être un booléen par le compilateur?

Répondre

2

Oui, l'auteur dit que ne avez pas besoin de préciser que a est un Boolean en myMethod({a => true}) parce que le type est Boolean => Boolean

== réponse originale qui fait le premier bit compilation mais rate le point un peu ==

Il devait être tapé avec [A,B]. Je l'ai modifié pour retourner la fonction afin que vous puissiez voir les types dans la réplique.

scala> def myMethod[A,B](functionLiteral: A => B): A => B = functionLiteral 
myMethod: [A, B](functionLiteral: (A) => B)(A) => B 

scala> myMethod((arg:String) => arg.length) 
res11: (String) => Int = <function1> 

scala> res11("hello world!") 
res12: Int = 12 

scala> myMethod((arg:Int) => (1 to arg).map(_ *2)) 
res13: (Int) => scala.collection.immutable.IndexedSeq[Int] = <function1> 

scala> res13(4) 
res14: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8) 
+0

Comment cela répond-il à la question concernant l'inférence? –

+0

Ah vous avez raison. J'étais confus par le fait que c'était le code qui ne pouvait pas compiler, mettra à jour la réponse. –

2

est l'auteur essaie de dire que l'argument est fonction d'une inférée d'être une valeur booléenne par le compilateur?

Absolument. Compte tenu de la méthode suivante:

def myMethod(functionLiteral: Boolean => Boolean):Unit = {} 

Le compilateur sait que le paramètre à myMethod est une fonction qui prend un paramètre booléen, donc il n'a pas besoin de vous le préciser. En d'autres termes, dans le a suivant est clairement un paramètre booléen:

myMethod{a => true} 

Maintenant, il convient de noter que cela ne fonctionne plus lorsqu'il est mélangé avec la surcharge:

def myMethod(functionLiteral: Boolean => Boolean):Unit = {} 
def myMethod(functionLiteral: Int => Boolean):Unit = {} 
myMethod{a => true} // error: missing parameter type 

La raison en est que ne peut pas dire sans ambiguïté si a est de type Boolean ou Int.

Questions connexes