2009-09-23 5 views
2

Voici le code POC:ne peut pas comprendre les erreurs de type à Scala

object TypeTest extends Application { 
    val stuff = List(1,2,3,4,5) 
    def joined:String = stuff.reduceLeft(_ + ", " + _) 

    println(joined) 
}                        

Lors de la compilation, il donne l'erreur suivante:

tt.scala:4: error: type mismatch; 
found : java.lang.String 
required: Int 
    def joined:String = stuff.reduceLeft(_ + ", " + _) 
                ^
tt.scala:4: error: type mismatch; 
found : Int 
required: String 
    def joined:String = stuff.reduceLeft(_ + ", " + _) 
           ^

Ecriture de la fonction rejoint comme

reduceLeft(_.toString + ", " + _.toString) 

ne aide pas, donne toujours la même erreur. Cependant, si je l'écris comme

def joined:String = stuff.map(_.toString).reduceLeft(_ + ", " + _) 

tout va bien. Est-ce que quelqu'un peut expliquer cette étrange combinaison d'erreurs de type? Qu'est-ce qui se passe vraiment ici? Le second est particulièrement bizarre, car il y a une conversion implicite pour Int en String.

Répondre

9

reduceLeft nécessite que le bloc de fonction (entre parenthèses) renvoie le même type que la collection. Cela est dû au fait que block est appelé de manière récursive jusqu'à ce que toutes les valeurs de la collection soient consommées. Stuff est une liste [Int], mais (_ + "," + _) est une chaîne, d'où l'erreur de type.

Une méthode similaire à reduceLeft est foldLeft. La distinction est que le type de collection et le type résultant peuvent être différents. Par exemple:

stuff.foldLeft("") { _ + ", " + _ } // => java.lang.String = , 1, 2, 3, 4 

Je suppose que votre exemple est une indication, mais si vous voulez vraiment une chaîne de valeurs séparées par des virgules, le suivant serait mieux:

stuff.mkString(", ") // => String = 1, 2, 3, 4 
+0

Ah, ouais, tu as raison. Je l'ai en quelque sorte confondu avec le pli * –

1

Je viens de commencer à utiliser Scala aussi. C'est ce que je comprends.

'stuff' est une liste de Int donc 'reduceLeft' nécessite un paramètre Int et renvoie un Int (base sur this). Mais vous mettez la chaîne comme un paramètre (erreur 1) et essayez d'affecter le résultat à la chaîne (erreur 2). C'est pourquoi vous avez de telles erreurs.

+0

Merci. Je l'ai maintenant. C'était assez stupide de ma part :) –

Questions connexes