scala Map filterKeys:无法将投影分配给Map参考

时间:2009-06-04 08:29:09

标签: scala maps projection

以下代码:

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]
  required:collection.this.Map [scala.this.Predef.String,scala.this.Int]
  m = m filterKeys {s =&gt; s.length&lt; 3}

我并不理解这一点,因为根据scaladoc Projection[A,B] 扩展了特性 Map[A,B+] 。也就是说,投影是地图

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

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

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

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

3 个答案:

答案 0 :(得分: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 }

但是,由于无法以返回collection.Map的方式添加地图,因此这没有多大帮助。我认为他们应该覆盖从++继承的Iterable方法,并将Map作为返回类型。

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

答案 1 :(得分:0)

我很好奇为什么你想要m而不是val - 如果你没有尝试将Map重新分配给它自己,事情似乎工作正常,如repl所示,这更符合斯卡拉哲学在可能的情况下更喜欢不变性:

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中你所看到的行为可能会有所不同。

答案 2 :(得分:0)

使用

m.view.filterKeys(x=>x.length <3).toMap