2014-09-27 70 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