scala Map filterKeys:无法将投影分配给地图引用

发布于 2024-07-22 17:43:20 字数 969 浏览 2 评论 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 过滤键 { s => s.长度< 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 : _ *) 

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

The following code:

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

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

Does not compile. I get the following error:

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 }

I don't really understand this as according to the scaladoc a Projection[A,B] extends the trait Map[A,B+]. That is, a Projection is a Map.

I thought it might be something to do with the contravariant type B but if I use Any instead of Int, it still doesn't compile. What am I missing? The solution is to do:

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

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

but this seems inelegant to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风透绣罗衣 2024-07-29 17:43:20

好的 - 这已经在 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 有什么用?

OK - this has been figured out with the help of the scala console:

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)

So the type inference is inferring m's type as being an immutable map. The following code will compile OK:

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

However, this is not much help as the map can not be added to in such a way as to return a collection.Map. I think that they should have overridden the ++ method inherited from Iterable with Map as the return type.

Could anyone comment on this? What use a collection.Map?

鸠书 2024-07-29 17:43:20

我很好奇为什么你希望 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 中看到的行为可能有所不同。

I'm curious why you want m to be var rather than val - if you're not trying to reassign the Map to itself, things seem to work OK, as shown in the repl, and this is more in keeping with the scala philosophy of preferring immutability where 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))

I see that the question is kind of old, it's possible that the behaviour you're seeing is different in Scala 2.8 given the major refactoring of the collections classes.

作业与我同在 2024-07-29 17:43:20

使用

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

use

m.view.filterKeys(x=>x.length <3).toMap
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文