Переопределение значения перечисления Scala - PullRequest
31 голосов
/ 24 марта 2010

Насколько я могу судить, в Scala есть определения класса Enumeration Value для Value (Int), Value (String) и Value (Int, String).

Кто-нибудь знает пример создания нового подкласса Value для поддержки другого конструктора?

Например, если я хочу создать объекты перечисления со значением (Int, String, String), как мне это сделать? Я хотел бы получить все остальные преимущества использования класса Enumeration.

Спасибо.

Ответы [ 4 ]

43 голосов
/ 24 марта 2010

Значения перечисления являются экземпляром класса Val. Этот класс можно расширить и добавить фабричный метод.

object My extends Enumeration {
    val A = Value("name", "x")
    val B = Value("other", "y")
    class MyVal(name: String, val x : String) extends Val(nextId, name)
    protected final def Value(name: String, x : String): MyVal = new MyVal(name, x)
}

scala> My.B.id
res0: Int = 1

scala> My.B.x
res1: String = y
1 голос
/ 09 октября 2011

На самом деле в Scala перечисление имеет гораздо более простое значение, чем в Java. Для вашей цели вам не нужно каким-либо образом создавать подкласс Enumeration или его Value, вам просто нужно создать экземпляр своего собственного типа в объекте-компаньоне как val. Таким образом, вы получите знакомую модель доступа val value:MyEnum = MyEnum.Value, как у вас на Java, что невозможно в примере, представленном Томасом Юнгом. Там у вас будет def value:My.MyVal = MyEnum.Value, что, как мне кажется, немного запутанно, помимо всего хакерства решения. Вот пример того, что я предлагаю:

class MyEnum(myParam:String)

object MyEnum {
  val Value1 = new MyEnum("any parameters you want")
  val Value2 = new MyEnum("")
  object Value3 extends MyEnum("A different approach to instantialization which also lets you extend the type in place")
}

Здесь вы найдете более сложный пример: Рекомендации Scala: Наследование признаков по сравнению с Перечислением

0 голосов
/ 08 февраля 2019

Я бы предпочел сделать это, расширив класс Enumeration.Val.

Для вашего требования, я бы опубликовал образец ниже:

object FileType extends Enumeration {
  val csv = Val(1,"csv", ",")
  val tsv = Val(2,"tsv", "\t")
  protected case class Val(num: Int, fileType: String, delimiter: String) extends super.Val
  implicit def valueToFileType(x: Value): Val = x.asInstanceOf[Val]
}

Доступ к значениям приведен ниже:

scala> FileType.csv
res0: FileType.Val = csv

scala> FileType.csv.delimiter
res29: String = ,
0 голосов
/ 11 апреля 2018

Вот еще один более простой подход:

scala> :paste
// Entering paste mode (ctrl-D to finish)

object Colors extends Enumeration {
  sealed case class Color private[Colors](hexCode: String, name: String) extends Val(name)

  val Black = Color("#000000", "black")
  val White = Color("#FFFFFF", "white")
}

// Exiting paste mode, now interpreting.

defined object Colors

scala> Colors.Black.hexCode
res0: String = #000000

scala> Colors.Black.name
res1: String = black

scala> Colors.values
res2: Colors.ValueSet = Colors.ValueSet(black, white)

scala> 
...