ChatGPT解决这个技术问题 Extra ChatGPT

理解 Scala 枚举

我不得不说我不懂 Scala 枚举类。我可以从文档中复制粘贴示例,但我不知道发生了什么。

object WeekDay extends Enumeration {
  type WeekDay = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._

什么是类型 WeekDay = Value 以及为什么我必须这样写?

为什么 val Mon = 价值?那有什么意思?

为什么我必须导入 WeekDay 对象?和,

当我写 val day = WeekDay.Mon 时,为什么输入 WeekDay.Value,而不是输入 WeekDay?

我写了一个关于 scala 枚举和替代方案的小概述,你可能会发现它很有用:pedrorijo.com/blog/scala-enums/
密封特征提供了一个很好的选择 - stackoverflow.com/questions/11203268/what-is-a-sealed-trait

0
0__

Enumeration 特征有一个类型成员 Value 表示枚举的各个元素(它实际上是一个内部类,但这里的区别并不重要)。

因此 object WeekDay 继承了该类型成员。 type WeekDay = Value 行只是一个类型别名。它很有用,因为在使用 import WeekDay._ 将其导入其他地方后,您可以使用该类型,例如:

def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun)

相反,最小版本将是:

object WeekDay extends Enumeration {
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}

并且您不必必须导入 object WeekDay 的内容,但是您需要使用类型 WeekDay.Value 并限定单个成员。所以这个例子会变成

def isWorkingDay(d: WeekDay.Value) = ! (d == WeekDay.Sat || d == WeekDay.Sun)

第二个问题是关于val Mon, ... = Value的含义。如果您不研究 Enumeration 的实现,这确实非常令人困惑。这不是类型的分配!相反,它调用了一个受保护的同名方法Value,它返回一个 Value 类型的具体实例。

碰巧您可以在 Scala 中编写 val a, b, c = foo,并且对于每个值 abc,方法 foo 将被一次又一次地调用。 Enumeration 使用这个技巧来增加一个内部计数器,以便每个值都是单独的。

如果您打开 Enumeration 的 Scala API 文档并单击 Visibility: All,您将看到该方法出现。


谢谢,这很令人困惑,但我认为这是正确的。我将改用密封案例类,这似乎 100% 容易。
我个人也更喜欢密封案例课程。更详细一点,但更少的 hokus-pokus 与可变的内部计数器等等。在 Scala 2.10 中,有一些想法如何使用宏更好地编写枚举(与 Java 不同,它不是一种语言结构,而只是一种库解决方案)。
@0__ 请问你为什么以及如何使用密封类来替换 Scala 中的枚举? Scala 的枚举有什么问题吗?
如果 Enum 值本身有成员怎么办?例如,您将如何定义一周中每一天的开放时间,例如: Mon(8,20), ..., Sun(0,0) ?
@simou 那么您确实应该使用密封的特征和实际的子类。不过,我几乎不会将这种情况称为“枚举”。您最好写 Open(Mon, 8, 20) 并且天数仍将是一个平面枚举。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅