Scala枚举和值组

时间:2014-02-08 14:01:25

标签: scala enums

我需要对Enumeration的一些值进行分组。

以下是代码:

object PostType extends Enumeration {
  // Documents
  val BOOKMARK = Value("bookmark")
  val FILE = Value("file")
  val NOTE = Value("note")
  val WIKIDOC = Value("wikidoc")

  …    
}

object PostTypes {
  type PostTypes = List[PostType.Value]
  val DOCUMENTS : PostTypes = List(PostType.BOOKMARK, PostType.FILE, PostType.NOTE, PostType.WIKIDOC)
  val QUESTIONS : PostTypes = List(PostType.QUESTION, PostType.QUICKPOLL, PostType.SURVEY)
  val EVENT : PostTypes = List(PostType.EVENT)
  …
  val ALL : PostTypes = PostType.values.toList
}

有更好的方法吗? 以下是我看到的缺点:客户端代码中的PostType.ValuePostTypes.PostTypes

[update]在两个答案的帮助下改进代码

object PostType extends Enumeration {
  // Documents
  val Bookmark = Value("bookmark")
  val File = Value("file")
  val Note = Value("note")
  val Wikidoc = Value("wikidoc")
  …
}

object PostTypes {
  import PostType._
  implicit def toList(pt: Value) = List(pt)

  type PostTypes = List[Value]
  val Documents = List(Bookmark, File, Note, Wikidoc)
  val Questions = List(Question, Quickpoll, Survey)
  val All = values.toList
}

[更新2]另一堆改进

object PostType extends Enumeration {
  type PostType = Value
  type PostTypes = List[Value]

  implicit def toList(pt: Value) = List(pt)

  // Documents
  val Bookmark = Value(1, "bookmark")
  val File = Value(2, "file")
  val Note = Value(3, "note")
  val Wikidoc = Value(12, "wikidoc")

  // Declare after Val to avoid runtime error
  val Documents = List(Bookmark, File, Note, Wikidoc)
  val Questions = List(Question, Quickpoll, Survey)
  val All = values.toList.sorted
}

3 个答案:

答案 0 :(得分:3)

以下是一种不使用枚举的方法,但希望能够实现您的目标。该示例显示如何从PostType实例中实例化String。如果String不匹配,则会抛出MatchError

package rando

object PostType {
  val all = Document.all ++ Question.all
  def fromString(s: String): PostType = Document.fromString.orElse(Question.fromString)(s)
}
sealed trait PostType

object Document {
  val all = Set(Bookmark, File, Note, Wikidoc)
  val fromString: PartialFunction[String, Document] = {
    case "bookmark" => Bookmark
    case "file" => File
    case "note" => Note
    case "wikidoc" => Wikidoc
  }
}
sealed trait Document extends PostType
case object Bookmark extends Document
case object File extends Document
case object Note extends Document
case object Wikidoc extends Document

object Question {
  val all = Set(SlowPoll, QuickPoll, Survey)
  val fromString: PartialFunction[String, Question]  = {
    case "slowpoll" => SlowPoll
    case "quickpoll" => QuickPoll
    case "survey" => Survey
  }
}
sealed trait Question extends PostType
case object SlowPoll extends Question
case object QuickPoll extends Question
case object Survey extends Question

object Example extends App {
  println(PostType.fromString("bookmark").getClass)
}

答案 1 :(得分:2)

除非你想使用替代枚举实现(参见我的回答here)或者只是使用一些常量,否则我认为这样做会很好。

我唯一可以建议的是定义类型别名type PostType = Value并使用它代替Value。我确定您知道,通过导入<package>.PostType._,您不必再将{1}}的枚举值加上前缀。

最后PostType似乎有点像矫枉过正,在阅读时很容易将它与PostTypes混淆。这些只是一些小问题。我使用与你相同的方法,我不知道什么更好。

答案 2 :(得分:0)

这是最终的代码,在其他答案的帮助下。 只需在客户端代码中import PostType._

object PostType extends Enumeration {
  type PostType = Value
  type PostTypes = List[Value]

  implicit def toList(pt: Value) = List(pt)

  // Documents
  val Bookmark = Value(1, "bookmark")
  val File = Value(2, "file")
  val Note = Value(3, "note")
  val Wikidoc = Value(12, "wikidoc")

  // Declare after Val to avoid runtime error
  val Documents = List(Bookmark, File, Note, Wikidoc)
  val Questions = List(Question, Quickpoll, Survey)
  val All = values.toList.sorted
}