如何从其他包引用scala Enumeration

Leo*_*ley 3 scala playframework-2.0

我无法理解为什么我不能引用scala枚举类型.

问题是有时我可以引用枚举:

enum(UserStatus)
Run Code Online (Sandbox Code Playgroud)

有时它抱怨无法找到枚举

not found: type UserStatus
Run Code Online (Sandbox Code Playgroud)

为什么我有时不能引用Enumeration类?

枚举的生成源似乎没问题,并且它与我生活在同一个地方的另一个枚举很有效,相同的用法......

有什么建议?

更多信息

生成的枚举源是:

public final class models.UserStatus extends java.lang.Object{
    public static final scala.Enumeration$Value Busy();
    public static final scala.Enumeration$Value Free();
    public static final scala.Enumeration$ValueSet$ ValueSet();
    public static final scala.Enumeration$Value withName(java.lang.String);
    public static final scala.Enumeration$Value apply(int);
    public static final int maxId();
    public static final scala.Enumeration$ValueSet values();
    public static final java.lang.String toString();
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试为play framework 2.0实现一个枚举映射器

def enumFormat[E <: Enumeration](enum: E): Formatter[E#Value] = new Formatter[E#Value] {
  def bind(key: String, data: Map[String, String]) = {
    Formats.stringFormat.bind(key, data).right.flatMap { s =>
      scala.util.control.Exception.allCatch[E#Value]
        .either(enum.withName(s))
        .left.map(e => Seq(FormError(key, "error.enum", Nil)))
    }
  }
  def unbind(key: String, value: E#Value) = Map(key -> value.toString)
}
Run Code Online (Sandbox Code Playgroud)

而这个调用mapper的方法

def enum[E <: Enumeration](enum: E): Mapping[E#Value] = of(enumFormat(enum))
Run Code Online (Sandbox Code Playgroud)

这意味着映射器在使用表单绑定时会自动在枚举之间进行转换

伪代码使用.

package models {
  object UserStatus extends Enumeration {
    val Free = Value("free")
    val Busy = Value("busy")
  }

  case class User(
    status: UserStatus.Value = UserStatus.Free
  )
}

package controllers {
  imports models._
  val userForm = Form(
    mapping(
      "status" -> enum(UserStatus)
    )(User.apply)(User.unapply)
  )
}
Run Code Online (Sandbox Code Playgroud)

Jul*_*Foy 8

您的问题可能来自以下事实:在Scala中,您可以对类型使用相同的标识符.

当您写下以下内容时:

object Foo extends Enumeration {
  val A, B, C = Value
}
Run Code Online (Sandbox Code Playgroud)

您定义了一个Foo 对象,但没有定义Foo 类型.如果您来自Java背景,则可能无法直观地发现此行为.

那么Foo枚举值的类型是什么?它们的类型是Foo.Value(称为路径依赖类型).

如果要定义Foo与枚举值类型对应的类型,可以为Foo.Value类型添加别名:

object Foo extends Enumeration {
  type Foo = Value    // Type alias
  val A, B, C = Value
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过编写来引用枚举类型Foo.Foo.您可以导入Foo对象的字段以减少语法开销:

import Foo._
def bar(foo: Foo): String = foo match {
  case A => "value A"
  case B => "value B"
  case C => "value C"
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,第一行引用了Foo 对象,第二行引用了Foo 类型.