从 mutable.Map 到 immutable.Map 的 O(1) 转换?
有没有办法在 O(1) 时间内将可变 Map 转换(包装)为不可变(也就是说,不是通过复制值,而是类似于 JavaConversions 中所做的)
Is there a way to convert (wrap) a mutable Map to immutable in O(1) time (that is, not by copying the values, but similar to what is done in JavaConversions)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
正如 Thomas 指出的,只读视图的复杂度为 O(1)。但只读并不等于不变性。
这种差异在“对抗位腐烂中得到了很好的描述”论文:
也许这只是简单的向上转换。
As Thomas points out, the read only view is O(1). But read-only doesn't equate to immutability.
The difference is well descrived in the "Fighting Bit Rot" paper:
Perhaps it's just a simple as up-casting.
有一个只读投影 对于可变映射。
正如 oxbow_lakes 指出 底层 Map 是仍然可变,并且在只读投影发布给客户端后可能会发生变化。不变性的错觉必须在管理地图的代码中解决。
There is a read only projection for mutable maps.
As oxbow_lakes pointed out the underlying Map is still mutable and may change after the read-only projection is published to clients. The illusion of immutability has to addressed in code managing the map.
您所要求的本质上是不安全的。您可以将
mutable.Map
作为不可变的collection.Map
传递,但使用此表单的“客户端”无法确定他们的视图不会从他们下面改变。What you are asking for is inherently unsafe. You can either pass the
mutable.Map
around as acollection.Map
which is immutable but "clients" using this form cannot be sure that their view will not change from under them.原则上可以向可变数据结构添加一种“冻结”方法,以防止进一步的突变。这是唯一稍微安全的包装方法。 (只有一点点,因为之后当你尝试改变它时,你必须抛出异常。)但是,Scala 的可变集合不具备此功能。人们可以通过覆盖所有变异方法(
update
、+=
、++=
等)将其添加到例如 mutable.HashMap 中,但是这将是一项相当大的工作。One could in principle add a "freeze" method to a mutable data structure that prevented further mutation. This is the only even slightly-safe way to do the wrapping. (Only slightly because after that you'd have to throw exceptions when you tried to mutate it.) Scala's mutable collections don't have this capability, however. One could add it to e.g. mutable.HashMap by overriding all mutating methods (
update
,+=
,++=
, etc.), but this would be a fair bit of work.Philipp Haller 在独特性和借用能力方面的工作与此相关。在通过类型系统强制执行“所有权”领域还有很多其他工作,但 Philipp 实际上为 Scala 编译器提供了一个可用的插件。
Philipp Haller's work on Capabilities for Uniqueness and Borrowing is related to this. There's a lot of other work in the domain of enforcing "ownership" through the type system, but Philipp actually provides a usable plugin to the Scala compiler.
类似这样的事情应该做,它类似于 ArraySeq.unsafeWrapArray 。
显然,在创建此映射后,您一定不能触摸可变映射!
一个更雄心勃勃的解决方案可能是创建一个映射,一旦创建了副本,就会设置一个内部标志,并且任何未来的突变都将导致可变实例在执行突变之前复制其内部状态。
Something like this should do, which is similar to
ArraySeq.unsafeWrapArray
.Obviously you must not touch the mutable map after creating this!
A more ambitious solution could be to create a map that, once a copy is created, sets an internal flag and any future mutation will cause the mutable instance to copy its internal state before performing mutations.