scala 如何在同一个枚举的前一个序数中使用枚举值?

w41d8nur  于 8个月前  发布在  Scala
关注(0)|答案(2)|浏览(95)

(FIG 1)我有以下枚举:

enum Paint(val components: Array[Paint]):
  case Red    extends Paint(Array())
  case Orange extends Paint(Array(Red, Yellow))
  case Yellow extends Paint(Array())
  case Green  extends Paint(Array(Yellow, Blue))
  case Blue   extends Paint(Array())
  case Purple extends Paint(Array(Red, Blue))
  def isPrimary: Boolean = components.isEmpty

(FIG 2)当我运行以下代码时:

@main def helloInteractive(): Unit =
  for
    p <- Paint.values
  do
    println(p.components.mkString(s"${p} is made from ", ", ", ""))

(FIG 3)我得到的输出是:

Red is made from 
Orange is made from Red, null
Yellow is made from 
Green is made from Yellow, null
Blue is made from 
Purple is made from Red, Blue

(FIG 4)但如果我将枚举改为:

enum Paint(val components: Array[Paint]):
  case Red extends Paint(Array())
  case Yellow extends Paint(Array())
  case Blue extends Paint(Array())
  case Orange extends Paint(Array(Red, Yellow))
  case Green extends Paint(Array(Yellow, Blue))
  case Purple extends Paint(Array(Red, Blue))
  def isPrimary: Boolean = components.isEmpty

(FIG 5)我在components中得到正确的值:

Red is made from 
Yellow is made from 
Blue is made from 
Orange is made from Red, Yellow
Green is made from Yellow, Blue
Purple is made from Red, Blue

我认为枚举是按顺序创建的,因此文件后面的内容还不存在。是这样吗?
我的问题是:
1.如何在保持图1中枚举序号的同时获得图5的值?
我不想排序,我想枚举。序数是图1。
1.这是一个坏主意吗?如果是,为什么?
这段代码是我在学习语言,它是玩具代码,不要担心它是愚蠢的或毫无意义的。

b0zn9rqh

b0zn9rqh1#

1.要在保持序号的同时获得正确的输出,最直接、最无警告的方法是使enum参数被称为by-name。也可以将其类型更改为LazyList,但如果使用安全初始化检查(-Ysafe-init),后者的当前实现将生成大量警告:

enum Paint(comps: => Array[Paint]):
      case Red    extends Paint(Array())
      case Orange extends Paint(Array(Red, Yellow))
      case Yellow extends Paint(Array())
      case Green  extends Paint(Array(Yellow, Blue))
      case Blue   extends Paint(Array())
      case Purple extends Paint(Array(Red, Blue))
      def isPrimary: Boolean = components.isEmpty
      lazy val components = comps

    import scala.collection.immutable.LazyList.empty
    enum Paint(val components: LazyList[Paint]):
      case Red    extends Paint(empty)
      case Orange extends Paint(Red #:: Yellow #:: empty)
      case Yellow extends Paint(LazyList.empty)
      case Green  extends Paint(Yellow #:: Blue #:: empty)
      case Blue   extends Paint(empty)
      case Purple extends Paint(Red #:: Blue #:: empty)
      def isPrimary: Boolean = components.isEmpty

1.您的用例似乎是合法的。

watbbzwu

watbbzwu2#

这不是我想要的,但这是一个解决方案:

enum Paint(private val baseColours: Array[String]):
  case Red    extends Paint(Array())
  case Orange extends Paint(Array("Red", "Yellow"))
  case Yellow extends Paint(Array())
  case Green  extends Paint(Array("Yellow", "Blue"))
  case Blue   extends Paint(Array())
  case Purple extends Paint(Array("Red", "Blue"))
  def isPrimary: Boolean = components.isEmpty
  def components: Array[Paint] = for bc <- baseColours yield Paint.valueOf(bc)

现在我得到了以下结果,而不必修改图2函数:

Red is made from 
Orange is made from Red, Yellow
Yellow is made from 
Green is made from Yellow, Blue
Blue is made from 
Purple is made from Red, Blue

相关问题