Domanda

Il seguente codice:

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

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

non può essere compilato. Ottengo il seguente errore:

  

errore: tipo non corrispondente
  trovato: collection.this.Map.Projection [scala.this.Predef.String, scala.this.Int]
  richiesta: collection.this.Map [scala.this.Predef.String, scala.this.Int]
  m = m Filtro {s => s.length <3}

Io non capisco questo come in base al scaladoc di un Projection[A,B] si estende il tratto Map[A,B+] . Cioè, una proiezione è una mappa .

Ho pensato che potrebbe essere qualcosa a che fare con il tipo controvariante B ma se uso Any invece di Int, ancora non la compilazione. Che cosa mi manca? La soluzione è quella di fare:

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

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

ma questo sembra poco elegante per me.

È stato utile?

Soluzione

OK - questo è stato capito, con l'aiuto della 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)

Quindi, il tipo di inferenza è inferire il tipo di m come una mappa immutabile. Il seguente codice compilerà OK:

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

Tuttavia, questo non è di grande aiuto, come la mappa non può essere aggiunto a in un modo tale da restituire un collection.Map. Credo che avrebbero dovuto ignorato il metodo ++ ereditato da Iterable con Map come tipo di ritorno.

Qualcuno potrebbe commentare su questo? Cosa usare un collection.Map?

Altri suggerimenti

Sono curioso perché si vuole m sia var anziché val - se non stai cercando di riassegnare la mappa a se stesso, le cose sembrano funzionare bene, come mostrato nella repl, e questo è più in linea con la filosofia alla Scala di immutabilità preferire, se possibile:

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))

vedo che la questione è un po 'vecchio, è possibile che il comportamento che stai vedendo è diverso in Scala 2.8 data la maggiore refactoring delle classi collezioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top