我正在尝试使用scala中的case类实现枚举。
参考问题type parameter in traits to define data types in scala
sealed trait ElementType[+A] {
def length: Int
}
sealed trait Tag extends ElementType[Int] {
override def length: Int = 0
}
case object Tag100 extends Tag
sealed trait Value[+A] extends ElementType[A] {
override def length: Int = 0
}
final case class Value100(a: String) extends Value[String] {
override def length: Int = a.length
}
case class MessageId(tag: Tag, value: Value[String]){
}
case class MessageRepType(tag: Tag[Int], value:MessageType ){
}
sealed trait Message[T] {def typeCode: T;}
object MessageTypes {
sealed trait MessageType[Int] extends Message[Int]
case object TYPE1 extends MessageType[Int]{val typeCode = 0;}
case object TYPE2 extends MessageType[Int]{val typeCode = 1;}
}
case class ABCMessage (
id:MessageId,
messageType:MessageRepType)
我想打印一条消息,其中包含以下ID并在新行中输入
type value
100 abc
200 0
说明: 100 abc代表MessageId 200 0 represnets MessageRepType和O代表TYPE1
答案 0 :(得分:0)
假设你的消息"是Tag200
(假设Tag100
与case class MessageRepType(tag: Tag[Int], value:MessageType)
类似,case class MessageRepType(tag: Tag, value:MessageType)
是sealed trait MessageType extends Message[Int]
和val sep = System.lineSeparator
def convertTag(tag: Tag): Int = tag match {
case Tag100 => 100
case Tag200 => 200
}
def convertMessageId(message: MessageId): String = {
val typ = convertTag(message.tag)
val value = message.value match {
case Value100(v) => v
}
s"$typ\t$value"
}
val id = convertMessageId(message.id)
def convertType(message: MessgeRepType): String = {
val typ = convertTag(message.tag)
val value = message.value match {// I would put typeCode to MessageType, but it is not there, so pattern matching
case TYPE1 => TYPE1.typeCode
case TYPE2 => TYPE2.typeCode
}
s"$typ\t$value"
}
val typ = convertType(message)
val message: ABCMessage = ABCMessage(MessageId(Tag100, Value100("abc"),MessageRepType(Tag200, TYPE1))
val messageAsString = Seq("type\tvalue", id, typ).mkString(sep)
println(messageAsString)
):
{{1}}
答案 1 :(得分:0)
一种不同的方法仍然不确定你想要实现什么。模式匹配的另一个答案是我更喜欢的,more idiomatic。
您可以使用简化的访客模式(删除不相关的部分):
trait Show {
def show: String
}
sealed trait Tag extends Show {
override def show: String = this.getClass.getSimpleName.init
}
//object Tag {
case object Tag100 extends Tag
case object Tag200 extends Tag
//}
这样你就可以显示这样的标签:
Tag100.show // Tag100
案例类还可以实现show
:
sealed trait Value[+A] extends Show {
def v: String
override def show: String = v
}
case class Value100(v: String) extends Value[String]
您也可以在其他方法中使用它来实现所需的打印:
def convertMessageId(message: MessageId): String = {
val typ = message.tag.show
val value = message.value.show
s"$typ\t$value"
}
val id = convertMessageId(message.id)
def convertType(message: MessgeRepType): String = {
val typ = message.tag.show
val value = message.value.show
s"$typ\t$value"
}
val message: ABCMessage = ABCMessage(MessageId(Tag100, Value100("abc"),MessageRepType(Tag200, TYPE1))
val messageAsString = Seq("type\tvalue", id, typ).mkString(sep)
println(messageAsString)
如果类型安全且容易,通用用法也很重要,请查看Shapeless'产品和this blog post。
如果类型安全性不是那么重要,也许对于您的用例,知道案例类实现Product
就足够了,因此您可以逐个访问它们并使用其内容。
替代解决方案可能是将您的数据结构转换为例如JSON(有许多Scala库)并将其用于进一步处理。仍然是通用的,但不是类型安全的。
(This question也可能相关。)