Scala 3 枚举方法覆盖

Анд*_*пов 3 enums scala anonymous-class scala-3

有没有办法像在 Java 中一样覆盖 Scala 3 枚举中的方法?

public enum Test {

    ONE {
        @Override
        public int calc() {
            return 1;
        }
    },
    TWO {
        @Override
        public int calc() {
            return 2;
        }
    };

    public abstract int calc();
}
Run Code Online (Sandbox Code Playgroud)

我试过这样的事情,但没有结果。在文档中也没有找到关于枚举方法覆盖的任何内容。

enum Test {
  def calc(): Int ={
    0
  }
  case One
    override def calc(): Int ={
      1
    }
  case Two
    override def calc(): Int ={
      2
    }
}
Run Code Online (Sandbox Code Playgroud)

也许有另一种方法可以实现类似的功能?

And*_*kin 5

enum是密封的,所以它不能在事后进行扩展,所以没有理由去override任何东西。只需在一个地方收集所有案例,而不是多个override-methods,编写一个涵盖所有案例的单一方法:

enum A:
  case X(x: Int)
  case Y(y: String)
  def foo: String = this match {
    case X(x) => s"X = ${x}"
    case Y(y) => y
  }

val x = new A.X(42)
val y = new A.Y("y")
println(x.foo) // X = 42
println(y.foo) // y
Run Code Online (Sandbox Code Playgroud)

  • @AndreiYusupau我认为“是”,因为1.不必为每个案例类重复`override def calc(): Int ={`-signature。2. `match` 是使用枚举的自然方式,这就是它们应该如何使用。“enum”本身的声明中不需要偏离标准的“match-case”。 (2认同)

use*_*ser 4

看来你想要的目前是不可能的,但还有其他方法可以做到。您可以尝试使用旧式密封特征来覆盖calc.

sealed trait Test:
  def calc: Int
object One extends Test:
  def calc = 1
object Two extends Test:
  def calc = 2
Run Code Online (Sandbox Code Playgroud)

该函数calc也可以作为 的参数Test,尽管我不太喜欢这种方法。

enum Test(calc: () => Int):
  case One extends Test(() => 1)
  case Two extends Test(() => 2)
Run Code Online (Sandbox Code Playgroud)

另一种方法是通过单一方法和模式匹配,就像 gianluca aguzzi 和 Andrey Tyukin 所做的那样,尽管扩展方法是不必要的。

如果calc必须是一个函数,我会建议第一种方法,或者模式匹配(如果您觉得它更适合您)。如果您想要重写多个方法,密封特征也是一个不错的选择,因为您不需要单独进行模式匹配或将一堆 lambda 集中到构造函数调用中。如果它不是一个功能,我觉得第二个效果最好。