4

なぜscala列挙型を参照できないのか理解できません。

問題は、列挙型を参照できる場合があることです。

enum(UserStatus)

列挙型が見つからないことについて不平を言うこともあります

not found: type UserStatus

列挙型クラスを参照できないことがあるのはなぜですか?

列挙型の生成されたソースは問題ないようで、同じ場所、同じ使用法に住んでいる私が持っている別の列挙型でうまく機能します...

助言がありますか?

より詳しい情報

列挙型の生成されたソースは次のとおりです。

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();
}

PlayFramework2.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)
}

そして、マッパーを呼び出すこのメソッド

def enum[E <: Enumeration](enum: E): Mapping[E#Value] = of(enumFormat(enum))

これは、フォームバインディングを使用すると、マッパーが列挙型間で自動的に変換することを意味します

使用法の擬似コード。

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)
  )
}
4

1 に答える 1

10

問題は、Scalaでは値に同じ識別子を使用できるという事実に起因している可能性があります。

あなたが以下を書くとき:

object Foo extends Enumeration {
  val A, B, C = Value
}

Foo オブジェクトを定義しますが、Foo タイプは定義しません。Javaのバックグラウンドを持っている場合、この動作は直感的ではないかもしれません。

Fooでは、列挙値のタイプは何ですか?それらの型は(パス依存型Foo.Valueと呼ばれます)です。

Foo列挙値タイプに対応するタイプを定義する場合は、Foo.Valueタイプのエイリアスを作成できます。

object Foo extends Enumeration {
  type Foo = Value    // Type alias
  val A, B, C = Value
}

これで、を記述して列挙型を参照できますFoo.Foo。オブジェクトのフィールドをインポートしてFoo、構文上のオーバーヘッドを減らすことができます。

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

上記のコードでは、最初の行はFoo オブジェクトを参照し、2番目の行はFoo タイプを参照しています。

于 2012-04-19T21:03:01.843 に答える