为什么懒惰的val在枚举中表现得如此神秘,Scala?

Mar*_*ról 1 enums scala lazy-evaluation

我想懒得找到所有已定义的枚举值名称的最大值.执行时下面的代码片段会反复进行无限循环打印InvocationTargetException.

object Enum extends Enumeration with App {
  val A, B = new Val
  lazy val foo = values.maxBy(_.toString)

  println(Enum.foo)
}
Run Code Online (Sandbox Code Playgroud)

当该问题不会出现foo是一个def.

为什么它会像这样?不lazy val应该只是一个记忆def

奇怪的是,下面的代码确实按预期工作:

object Enum extends Enumeration with App {
  val A, B = new Val
  lazy val foo = values.foldLeft(""){(a, b) => a + b}

  println(Enum.foo)
}
Run Code Online (Sandbox Code Playgroud)

我正在使用scala 2.11.7.

// ---解决方案

问题是foo是Value类型的,因此被解释为枚举值.解决问题的方法是创建一个代理def,lazy val如下面的代码:

object Enum extends Enumeration with App {
  val A, B = new Val
  private lazy val fooBuffer = values.maxBy(_.toString)
  def foo = fooBuffer

  println(Enum.foo)
}
Run Code Online (Sandbox Code Playgroud)

som*_*ytt 5

这两个问题App必须由初始化Enum main null.

然后,Enumeration查找类型的val Val,其中包括您的成员foo,这可能不是预期的.

样本混乱:

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

object Enum extends Enumeration with App {
  val A, B = new Val
  lazy val foo = values.maxBy(_.toString)

  println(Enum.foo)
}

// Exiting paste mode, now interpreting.

defined object Enum

scala> Enum main null
foo

scala> Enum.foo
res2: Enum.Value = foo

scala> Enum.values
res3: Enum.ValueSet = Enum.ValueSet(A, foo)
Run Code Online (Sandbox Code Playgroud)

只是为了表明修复类型修复了SO:

scala> object X extends Enumeration { val x, y, z = new Val ; lazy val f: Any = values.maxBy(_.toString) }
defined object X

scala> X.f
res2: Any = z
Run Code Online (Sandbox Code Playgroud)