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)
您的问题可能来自以下事实:在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 类型.