2011-05-26 149 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