2009-06-04 5 views
0

Le code suivant:scala Carte FilterKeys: Projection ne peut être attribué à une référence de la carte

var m: Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3) 

m = m filterKeys { s => s.length < 3 } 

Ne compile. Je reçois l'erreur suivante:

error: type mismatch
found: collection.this.Map.Projection[scala.this.Predef.String,scala.this.Int]
required: collection.this.Map[scala.this.Predef.String,scala.this.Int]
m = m filterKeys { s => s.length < 3 }

Je ne comprends pas vraiment ce que selon la scaladoc un Projection[A,B] étend le trait Map[A,B+]. C'est-à-dire, une projection est une carte.

Je pensais que cela pourrait être quelque chose à voir avec le type contravariant B mais si j'utilise Any au lieu de Int, il ne compile toujours pas. Qu'est-ce que je rate? La solution est de faire:

var m: Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3) 

m = Map(m filterKeys { s => s.length < 3 } toSeq : _ *) 

mais cela me semble inélégant.

Répondre

0

OK - cela a été compris avec l'aide de la console scala:

scala> var m = Map("A" -> 1, "BB" -> 2, "CCC" -> 3) 
m: scala.collection.immutable.Map[java.lang.String,Int] = Map(A -> 1, BB -> 2, CCC -> 3) 

Ainsi, l'inférence de type infère type de m comme une carte immuable. Le code suivant compilera OK:

var m: collection.Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3) 
m = m filterKeys { s => s.length < 3 } 

Cependant, ce n'est pas beaucoup d'aide que la carte ne peut pas être ajouté à une manière de retourner un collection.Map. Je pense qu'ils auraient dû remplacer la méthode ++ héritée de Iterable avec Map comme type de retour.

Quelqu'un peut-il commenter cela? À quoi servent les collection.Map?

0

Je suis curieux de savoir pourquoi vous voulez que m soit var plutôt que val - si vous n'essayez pas de réaffecter la carte à elle-même, les choses semblent fonctionner correctement, comme indiqué dans le repl, et c'est plus en accord avec la philosophie de scala de préférer immuabilité si possible:

scala> val m = Map("A" -> 1, "BB" -> 2, "CCC" -> 3) 
m: scala.collection.immutable.Map[java.lang.String,Int] = Map((A,1), (BB,2), (CCC,3)) 

scala> val n = m filterKeys { s => s.length < 3 } 
n: scala.collection.immutable.Map[java.lang.String,Int] = Map((A,1), (BB,2)) 

Je vois que la question est un peu vieux, il est possible que le comportement que vous voyez est différent à Scala 2.8 compte tenu de la modification majeure des classes de collections.

+0

En fait, cela * fonctionne * dans Scala 2.8. –

Questions connexes