2011-05-26 302 views
1

有時候,我建立一個類我想有一個reset功能。例如初始化變量

class DFA(val initialState:State) { 
    var states = Map[State,State]() 
    var currentState: State = initialState 
    reset 
    def reset {currentState = initialState} 
} 

糟糕!你的DRY鈴聲響了嗎?我將currentState設置爲initialState兩次。一旦在reset並且一次在構造函數中。我不能讓var未初始化,否則編譯器會報錯。

當然,我可以

class DFA(val initialState:State) { 
    var states = Map[State,State]() 
    var evilNullVariableWeMustNeverUse = null 
    var currentState: State = evilNullVariableWeMustNeverUse 
    reset 
    def reset {currentState = initialState} 
} 

,但我認爲,這種方法的缺點是顯而易見的。

在這個簡單的例子,它不是那麼糟糕,但如果你有5個變量,或更復雜的邏輯,它變得討厭。

我怎樣才能設計出解決此問題?

+0

你可以用「_」來設置的初始值。另外,爲什麼'重置'一個var?應該是一個def。然後你可以在構造函數中調用它。 – IttayD 2011-05-26 06:11:28

+0

'var reset',這是一個錯字嗎?正如IttayD暗示你可能是指'def reset {...}'。我真的不明白第一個解決方案不是對發生的事情和意圖的最清晰表達。除了它應該是'class DFA(val initialState:State)'或'class DFA(initialState:State)',因爲重置爲可能改變的狀態是沒有意義的。 Kim的答案交易一個'initialState'作爲額外的「重置」。 IttayD仍然提到「初始」3次。這是幹什麼的? – huynhjl 2011-05-26 06:45:39

+0

在我的解決方案中,DFA提到最初只有2次。此外,假設初始計算,而不是一個構造函數的參數,然後復位,就沒有必要將其存儲在類 – IttayD 2011-05-26 07:53:47

回答

3

也許創造一個複式包裝?

class Resettable[T](initial: T) { 
    var value: T = initial 
    def reset = value = initial 
    def :=(other: T) = value = other 
} 

object Resettable { 
    implicit def resettable[T](initial: T) = new Resettable(initial) 
    implicit def fromResettable[T](r: Resettable[T]) = r.value 
} 

然後:

class DFA(initialState:State) { 
    var states = Map[State,State]() 
    var currentState: Resettable[State] = initialState 
    def changeState(other: State) = currentState := other 

    def reset = currentState.reset 
} 

和:

val dfa = new DFA(new State) 
val t: State = dfa.currentState 

的好處可以看出:

class Something { 
    val a: Resettable[Int] = 0 
    val b: Resettable[String] = "hi" 
} 

有沒有需要存儲0"hi"在另一變量爲了重置。

1
class DFA(var initialState:State) { 
    var states = Map[State,State]() 
    var currentState: State = _ 
    var reset {currentState = initialState} 
    reset 
} 
+0

嗯,它有效地將其設置爲空,對不對? – 2011-05-26 11:43:23

+0

首先它被設置爲null,但是然後構造器調用reset,將其設置爲最終值。 – 2011-05-26 13:00:36

+0

是的。和我的例子一樣。我很喜歡編譯器允許我在構造函數調用的函數中初始化變量。但我想這是不可能的。 – 2011-05-26 13:42:10

2

使它不可變,並使「變異」方法返回一個新實例。

然後,如果你知道你可能需要在某個時候恢復到初始狀態,只是確保你扶住對象的引用作爲初始配置。

+0

這是少了類型安全。如果我這樣做,我的DFA可能會獲得另一個具有不同狀態表的DFA。如果我保持它可變,那麼'val dfa = DFA.fromFile(「f.dfa」)'總是代表'f。dfa',我不能將它與'DFA.fromFile(「b.dfa」)'偶然分配。除非我編碼狀態表的類型...... – 2011-05-26 13:47:01