Scala:如何实现自定义枚举
下面是我的自定义Scala:如何实现自定义枚举,scala,Scala,下面是我的自定义枚举 object DocState extends Enumeration { thisenum => type DocState = State val New = Value("new", new FromNew) val Open = Value("open", new FromOpen) class State(name: String, convertWith: Transduction) extends Val(name) {
枚举
object DocState extends Enumeration { thisenum =>
type DocState = State
val New = Value("new", new FromNew)
val Open = Value("open", new FromOpen)
class State(name: String, convertWith: Transduction) extends Val(name) {
def apply(message: Save) = convertWith(message)
def apply(message: Edit) = convertWith(message)
}
protected final def Value(
name: String, convertWith: Transduction
) = new State(name, convertWith)
sealed trait Message
case class Save(text: String) extends Message
case class Edit(text: String) extends Message
def apply(name: String) = thisenum.withName(name).asInstanceOf[State]
}
trait Transduction {
def apply(message: Save)
def apply(message: Edit)
}
class FromNew extends Transduction {
def apply(message: Save): DocState = { ... }
def apply(message: Edit): DocState = { ... }
}
class FromOpen extends Transduction {
def apply(message: Save): DocState = { ... }
def apply(message: Edit): DocState = { ... }
}
。。。它的工作原理如下:
import DocState._
val currentState = New(Save("hello")) // currentState is New
val newState = currentState(Edit("hello")) // newState is Open
上面的代码运行良好。。。但是New
和Open
是State
的实例,而不是DocState
的实例,当需要枚举时,这是一个问题,如下例所示:
trait DocException[S <: Enumeration] extends ServiceException {
val state: Option[S]
}
object DocException {
def apply[S <: Enumeration](message: String, _state: Option[S]) = new RuntimeException(message) with DocException[S] {
val state: Option[S] = _state
}
}
我总是收到以下错误消息:
inferred type arguments [test.DocState.DocState] do not conform to method apply's type parameter bounds [S <: Enumeration]
[error] val e = DocException("state error", Some(New))
/home/j3d/Projects/test/app/DocFsm.scala:71: type mismatch;
[error] found : Some[test.DocState.DocState]
[error] required: Option[S]
[error] val e = DocException("state error", Some(New))
推断的类型参数[test.DocState.DocState]不符合方法apply的类型参数界限[s最后,我能够为我的状态机获得正确的实现:
object DocState extends Enumeration { thisenum =>
type DocState = Value
val New = Value("new", new FromNew)
val Open = Value("open", new FromOpen)
class Val(name: String, convertWith: Transduction) extends super.Val(name) {
def !(message: Save) = convertWith(message)
def !(message: Edit) = convertWith(message)
}
private def Value(name: String, convertWith: Transduction) = new Val(name, convertWith)
sealed trait Message
case class Save(text: String) extends Message
case class Edit(text: String) extends Message
def apply(name: String) = thisenum.withName(name).asInstanceOf[Val]
implicit def toVal(value: Value) = value.asInstanceOf[Val]
implicit def toString(state: DocState) = state.toString
}
trait Transduction {
def apply(message: Save)
def apply(message: Edit)
}
class FromNew extends Transduction {
def apply(message: Save): DocState = { ... }
def apply(message: Edit): DocState = { ... }
}
class FromOpen extends Transduction {
def apply(message: Save): DocState = { ... }
def apply(message: Edit): DocState = { ... }
}
import DocState._
// initialize the state machine
val state1 = DocState("new") // state1 is New
// send an edit message to state1
val state2 = state1 ! Edit("my comment") // state2 is Edit
下面是如何使用状态机的示例:
object DocState extends Enumeration { thisenum =>
type DocState = Value
val New = Value("new", new FromNew)
val Open = Value("open", new FromOpen)
class Val(name: String, convertWith: Transduction) extends super.Val(name) {
def !(message: Save) = convertWith(message)
def !(message: Edit) = convertWith(message)
}
private def Value(name: String, convertWith: Transduction) = new Val(name, convertWith)
sealed trait Message
case class Save(text: String) extends Message
case class Edit(text: String) extends Message
def apply(name: String) = thisenum.withName(name).asInstanceOf[Val]
implicit def toVal(value: Value) = value.asInstanceOf[Val]
implicit def toString(state: DocState) = state.toString
}
trait Transduction {
def apply(message: Save)
def apply(message: Edit)
}
class FromNew extends Transduction {
def apply(message: Save): DocState = { ... }
def apply(message: Edit): DocState = { ... }
}
class FromOpen extends Transduction {
def apply(message: Save): DocState = { ... }
def apply(message: Edit): DocState = { ... }
}
import DocState._
// initialize the state machine
val state1 = DocState("new") // state1 is New
// send an edit message to state1
val state2 = state1 ! Edit("my comment") // state2 is Edit
我希望这能有所帮助。我不太明白您想做什么,但是枚举
有一些问题使得它不安全,而且看起来您正在以一种非常不寻常的方式使用它。最好像使用消息
一样,将密封类与case类/对象模式一起使用。我使用枚举来创建有限状态机。