簡體   English   中英

如何在保留不變性的同時訪問Scala中的復雜數據結構?

[英]how to access complex data structures in Scala while preserving immutability?

致電Scala專業開發人員! 假設您有一個代表可寫數據存儲的大對象。 您是否喜歡這種常見的類似Java的方法:

val complexModel = new ComplexModel()
complexModel.modify()
complexModel.access(...)

還是您更喜歡:

val newComplexModel = complexModel.withADifference
newComplexModel.access(...)

如果您願意這樣做,並且有一個客戶端訪問模型,那么客戶端將如何知道指向newComplexModel而不是complexModel? 從用戶的角度來看,您具有可變的數據存儲。 您如何將這種觀點與Scala對不變性的強調相協調?

這個怎么樣:

var complexModel = new ComplexModel()
complexModel = complexModel.withADifference
complexModel.access(...)

這似乎有點類似於第一種方法,除了withADifference內部的代碼似乎比Modify()內部的代碼需要做更多的工作外,因為它必須創建一個全新的復雜數據對象而不是修改現有的對象。 您是否遇到了在保持不變性方面不得不做更多工作的問題?)而且,您現在擁有一個具有較大范圍的var。

您將如何決定最佳策略? 您選擇的策略是否有例外?

我認為功能性的方法是實際上使Stream包含您數據結構的所有不同版本,而使用者只是嘗試從該流中提取下一個元素。

但是我認為在Scala中,這是絕對有效的方法,可在一個中心位置進行可變引用,並在您整個數據結構保持不變的情況下進行更改。

當數據結構變得更加復雜時,您可能會對以下問題感興趣: 一種更清晰的方法來更新嵌套結構 ,該結構詢問(並得到回答)如何實際創建不平凡的不可變數據結構的新更改版本。

對您問題的規范答案是使用Zipper ,這是一個有關SO的問題

我知道的唯一Scala實現是在ScalaZ中

通過僅modify方法的名稱,很容易將您的ComplexModel識別為modify器對象,這意味着它會更改某些狀態。 這僅意味着此類對象與函數式編程無關,並試圖使其變得不可變,只是因為某個知識淵博的人告訴您,Scala中的所有內容都應當不可變,這只是一個錯誤。

現在您可以修改您的api,以便此ComplexModel對不可變數據進行操作,我想您應該這樣做,但您絕對不能嘗試將此ComplexModel轉換為不可變本身。

不變性只是有用的工具,而不是教條。 出現不可變性的代價和不便超過其用途的情況。

ComplexModel的大小可能會使得在內存和/或CPU方面創建修改后的副本非常昂貴,因此可變模型更為實用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM