2014-09-27 40 views
1

是否有任何“好”的代码模式来初始化和填充私有可变映射,然后将它们公开为不可变的映射?还是应该在这种情况下永久性地后悔我的功能性不当行为?斯卡拉 - 初始化可变映射并将它们公开为不可变

在某个类中,我将一些Maps初始化为可变的,因为初始化它们的逻辑并不十分自然,在这种情况下,使用纯可变创建方法。或者,我只是懒惰地模仿它。

现在,我得到了Scala丑陋的代码 - 经过所有的初始化计算,我将可变映射复制转换为不可变映射(主要通过.toMap)。这已经很丑陋了,因为(1)代码有两倍的地图和双重命名感觉有点偏离,(2)转换线看起来比我希望的更多参与。因为它们只能在初始化计算之后声明,所以我不喜欢所得到的不可变映射的类型定义,现在它们只能驻留在代码的底部(或者,它们是否可以被定义为lazy并移动到顶端?仍然不完美)。

任何方式来优雅地包装可变的地图初始化代码?

+0

关于(2):您可以在可变映射上调用'toMap'来获取不可变的版本。你能为整个问题提供一个小例子吗? – Kigyo 2014-09-27 21:05:17

+1

考虑在调用构造函数之前使用辅助构造函数(或伴随对象方法)创建最终的不可变数据。这应该消除懒惰和坚持原始可变结构的需要 - 授予它仍然是重建过程和新对象。 – user2864740 2014-09-27 21:08:39

+0

是不是像一个不可变的视图或投影? – matanster 2014-09-27 21:09:54

回答

3

喜欢的东西:

scala> class X { 
    | private val mb = collection.immutable.Map.newBuilder[String, Int] 
    | def m = mb.result 
    | mb += ("a" -> 1) // stuff 
    | } 
defined class X 

scala> new X().m 
res0: scala.collection.immutable.Map[String,Int] = Map(a -> 1) 
+0

不知道为什么这已被低估,但它看起来确实合适。我看到它的方式提供了使用可变属性的性能属性来构建地图的能力,并将其自动公开为不可变的。任何类型的缺点? – matanster 2014-09-28 13:48:30

+0

是否有类似的其他不可变集合的构建方法? – matanster 2014-09-28 13:49:43

+0

@matt有人想对丑陋的可变性感到内疚。他们可能是对的。 – 2014-09-28 15:29:53

0

我认为使用immutables宁可val小号mutables的var S,根据我的初始化逻辑演进的var集合,可以是最佳的模式(如适用)。没有重复的集合,没有代码要从不可变到可变的,在类的顶部清除类型定义...

但是,我的理解是,这种功能方式与运行时间效率折衷为可变集合在构建它们时运行修改逻辑时可以提供更好的修改性能。

+0

正如我的编辑所说,对于一些条目的地图,不可变的在时间和空间上可能是最佳的。 – 2014-09-28 19:26:45