如何使用scala中的case类获取枚举值

时间:2017-08-06 17:05:01

标签: scala

我正在尝试使用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

2 个答案:

答案 0 :(得分:0)

假设你的消息"是Tag200(假设Tag100case 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也可能相关。)