scala Enumeration with constructor and lookup table 用构造函数和查找表的方式实现的Scala枚举

17 浏览
0 Comments

scala Enumeration with constructor and lookup table 用构造函数和查找表的方式实现的Scala枚举

我在某个地方看到了以下关于枚举的解决方案:

object Day {
  val values = new ArrayBuffer[Day]
  case class Day(name:String) {
    values += this
  }
  val MONDAY = new Day("monday")
  val TUESDAY = new Day("tuesday")
}

这个示例展示了我想要实现的内容,但是在ArrayBuffer中有一个隐藏的var变量,有点不好。

我真正想要的是一个val lookupTable = Map(),当有请求时,我可以查找"monday"并将其转换为我的枚举MONDAY,并在整个软件中使用该枚举。通常怎么做呢?我看到了密封特质(sealed traits),但没有看到一种自动确保当有人添加一个继承它的类时,它会自动添加到查找表中的方法。有办法创建一个带有查找表的Scala枚举吗?

Scala的Enumeration似乎接近,因为它有一个values()方法,但我不知道如何传入表示日期的字符串,这是我们从用户那里收到的,然后将其转换为枚举。

谢谢,

Dean

0
0 Comments

问题的出现原因是希望创建一个具有构造函数和查找表的 Scala 枚举。这种需求可能是因为希望在枚举中添加额外的构造函数参数和方法。

解决方法是使用 Scala 的 Enumeration 类,并通过创建一个继承 Enumeration.Val 的 sealed case class 来实现具有构造函数的枚举。

下面是解决方法的示例代码:

object Currency extends Enumeration {
  sealed case class CurrencyVal(name: String, value: Int) extends Val(name) {
    def *(n: Int): Int = n * value
  }
  val PENNY   = CurrencyVal("penny", 1)
  val NICKLE  = CurrencyVal("nickle", 5)
  val DIME    = CurrencyVal("dime", 10)
  val QUARTER = CurrencyVal("quarter", 25)
  override def withName(name: String): CurrencyVal = {
    super.withName(name).asInstanceOf[CurrencyVal]
  }
}

在上述代码中,CurrencyVal 是一个带有额外构造函数参数的 sealed case class,它继承自 Enumeration.Val。在 Currency 对象中,我们定义了几个具体的 CurrencyVal 实例,每个实例都具有不同的名称和值。

通过重写 withName 方法,我们可以确保调用 withName 方法时返回的是 CurrencyVal 而不是默认的 Currency.Value。

通过这种方式,我们可以实现具有构造函数和查找表的 Scala 枚举。这种枚举可以包含多个参数,例如整数代码、toString 版本等。

这样的解决方案可以满足需要将代码映射到枚举的情况,并且在枚举中添加更多的构造函数参数和方法时也能正常工作。同时,这种解决方案还能够防止枚举值被重命名时出现问题。

0
0 Comments

问题的出现原因是作者想要创建一个Scala枚举(enum)并希望能够自动地将新添加的子类添加到查找表(lookup table)中。作者提到了他之前看到过密封特质(sealed traits),但没有找到一种自动将扩展该特质的子类添加到查找表中的方法。

为了解决这个问题,作者介绍了一个名为Enumeratum的小型库。使用该库的方法如下:

import enumeratum._
sealed abstract class Day(val entryName: String) extends EnumEntry
case object Day extends Enum[Day] {
  val values = findValues
  case object MONDAY extends Day("monday")
  case object TUESDAY extends Day("tuesday")
  // etc
}
Day.withName("monday") // 返回 MONDAY

这段代码中,首先引入了`enumeratum`库。然后定义了一个名为`Day`的密封抽象类,该类有一个名为`entryName`的参数。`Day`对象继承了`Enum[Day]`,并且定义了一个`values`值,该值会在编译时自动将声明的子类添加到一个映射表中。在子类中,每个具体的枚举值都有一个对应的`entryName`值。

通过调用`Day.withName("monday")`方法,可以返回对应的枚举值`MONDAY`。

通过使用Enumeratum库,作者成功解决了创建Scala枚举并自动添加子类到查找表的问题。

0