我試圖模擬一個我試圖實作不變性而不是修改實體變數的場景。我實作這一目標的方式如下。
case class TSS(k:Int, v:Int)
case class Combiner(a:Int,b:Int, tss: TSS) {
def func1():Option[TSS] = None
def func2():Option[TSS] = None
def modifyState(externalV: Int): Combiner = {
Combiner(this.a 1, this.b 1, func1())
}
}
case class OneCombiner extends Combiner {
override def func1():Option[TSS] = SOME_MODIFIED_TSS
override def func2():Option[TSS] = SOME_MODIFIED_TSS
}
case class TwoCombiner extends Combiner {
override def func1():Option[TSS] = SOME_MODIFIED_TSS
override def func2():Option[TSS] = SOME_MODIFIED_TSS
}
現在,當我嘗試使用OneCombiner
andTwoCombiner
時,他們正在使用基類的 and 并將值設定為func1
to而不是使用覆寫的版本。func2
tss
None
例如
val a:Combiner = OneCombiner
val anotherCombiner = a.modifyState()
在這種情況下anotherCombiner.tss
,回傳為None
而不是SOME_TSS_VALUE
.
在 Scala 中建模這種行為的正確功能方法是什么?
我也嘗試過制作,Combiner
abstract case class
但編譯失敗,因為那時我無法在方法中創建Combiner
物件。modifyState
uj5u.com熱心網友回復:
問題是modifyState
創建一個新的Combiner
而不是適當的子類。這是因為它將狀態與抽象行為結合在一個類中。
最好的解決方案是創建一個單獨的具體State
類,并將Combiner
s 作為函式,接受 aState
并回傳一個新的。這將不同的行為與實際狀態本身分開。
case class TSS(k: Int, v: Int)
case class State(a: Int, b: Int, tss: TSS)
trait Combiner {
def func1(): TSS
def modifyState(state: State, externalV: Int): State
= State(state.a 1, state.b 1, func1())
}
case class OneCombiner() extends Combiner {
def func1(): TSS = ???
}
case class TwoCombiner() extends Combiner {
def func1(): TSS = ???
}
如果要保留單個類,則需要為每個子類有一個單獨的建構式,最簡單的方法是使modifyState
virtual 并在每個子類中實作它。目前尚不清楚還有多少其他值需要在其中公開,trait
因此我將它們全部放入,以防萬一。
case class TSS(k: Int, v: Int)
trait Combiner {
def a: Int
def b: Int
def tss: TSS
def func1(): Option[TSS]
def func2(): Option[TSS]
def modifyState(externalV: Int): Combiner
}
case class OneCombiner(a: Int, b: Int, tss: TSS) extends Combiner {
override def func1(): Option[TSS] = ???
override def func2(): Option[TSS] = ???
def modifyState(externalV: Int): OneCombiner =
OneCombiner(this.a 1, this.b 1, func1().getOrElse(???))
}
case class TwoCombiner(a: Int, b: Int, tss: TSS) extends Combiner {
override def func1(): Option[TSS] = ???
override def func2(): Option[TSS] = ???
def modifyState(externalV: Int): TwoCombiner =
TwoCombiner(this.a 1, this.b 1, func1().getOrElse(???))
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/477944.html