scala Carte FilterKeys: Projection ne peut être attribué à une référence de la carte
-
09-09-2019 - |
Question
Le code suivant:
var m: Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3)
m = m filterKeys { s => s.length < 3 }
Ne pas compiler. Je reçois l'erreur suivante:
erreur: incompatibilité de type
trouvé: collection.this.Map.Projection [scala.this.Predef.String, scala.this.Int]
nécessaire: collection.this.Map [scala.this.Predef.String, scala.this.Int]
m = m = {s FilterKeys> s.length <3}
Je ne comprends pas vraiment ce que selon le scaladoc Projection[A,B]
étend le trait Map[A,B+]
. Autrement dit, une projection est une carte .
Je pensais que ce serait peut-être quelque chose à voir avec le type contravariant B
mais si je l'utilise Any
au lieu de Int
, il ne fonctionne toujours pas compiler. Qu'est-ce que je rate? La solution consiste à faire:
var m: Map[String, Int] = Map("A" -> 1, "BB" -> 2, "CCC" -> 3)
m = Map(m filterKeys { s => s.length < 3 } toSeq : _ *)
mais cela semble inélégant pour moi.
La solution
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)
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 autant d'aide que la carte ne peut pas être ajouté à une manière de retourner un collection.Map
. Je pense qu'ils auraient dû la méthode substituée ++
héritée de Iterable
avec Map
comme type de retour.
Quelqu'un pourrait-il un commentaire à ce sujet? Que utiliser un collection.Map
?
Autres conseils
Je suis curieux de savoir pourquoi vous voulez être m var plutôt que val - si vous n'êtes pas essayer de réaffecter la carte elle-même, les choses semblent fonctionner OK, comme indiqué dans le rempl, ce qui est plus conforme à 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.