0

以下代码:

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

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

不编译。我收到以下错误:

错误:发现类型不匹配
:collection.this.Map.Projection[scala.this.Predef.String,scala.this.Int]
必需:collection.this.Map[scala.this.Predef.String,scala.this.Int]
m = m filterKeys { s => s.length < 3 }

我真的不明白这一点,因为根据scaladoc a Projection[A,B]extends the trait Map[A,B+]。也就是说,Projection 是 Map

我认为这可能与逆变类型有关,B但如果我使用Any而不是Int,它仍然无法编译。我错过了什么?解决办法是:

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

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

但这对我来说似乎很不雅。

4

3 回答 3

0

好的 - 这已经在 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)

所以类型推断将 m 的类型推断为不可变映射。以下代码将编译成功:

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

但是,这并没有多大帮助,因为无法以返回 a 的方式添加地图collection.Map。我认为他们应该重写从with作为返回类型++继承的方法。IterableMap

有人可以对此发表评论吗?有什么用collection.Map

于 2009-06-04T09:11:31.373 回答
0

我很好奇为什么您希望 m 成为 var 而不是 val - 如果您不尝试将 Map 重新分配给自身,事情似乎工作正常,如 repl 所示,这更符合 scala 哲学在可能的情况下更喜欢不变性:

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

我看到这个问题有点老了,考虑到集合类的主要重构,您在 Scala 2.8 中看到的行为可能有所不同。

于 2011-05-02T02:16:43.010 回答
0

采用

m.view.filterKeys(x=>x.length <3).toMap
于 2020-04-04T08:18:53.370 回答