Сравнение строки и перечисления - PullRequest
10 голосов
/ 04 августа 2010

У меня есть перечисление в scala, сопоставленное со строками в JPA.Для более удобного кодирования я определил неявные преобразования между ними.Так что теперь я могу определить значение val person.role = "User", - person.role - это тип перечисления "User" a String, так что есть преобразование.Но когда я пытаюсь сравнить эти два, я всегда получаю ложь, потому что def equals (arg0: Any) : Boolean берет Any, поэтому не происходит никакого преобразования.Мне нужно какое-то явное преобразование, но мой план состоял в том, чтобы опустить это, что, по вашему мнению, является лучшей практикой |самое лучшее решение здесь?

Ответы [ 2 ]

16 голосов
/ 04 августа 2010

Value("User") в вашем Enumeration имеет тип Val.И я считаю, что реализация equals не сравнивает строковое имя значения.Я думаю, что один сложный способ сделать это - создать свои собственные Enumeration и Val, чтобы он возвращал true, если имя совпадает.

Но в моем коде используется, а не с JPA, я всегда конвертируюстрока в MyEnumeration.Value.Это легко сделать с такими вещами, как:

 object E extends Enumeration { val User = Value("User") }

 scala> val a = E.withName("User")
 a: E.Value = User

Обратите внимание, что при использовании withName, если строка не соответствует ни одному имени в перечислении, вы получаете исключение.

Затем всегда используйтеполя перечисления в ваших сравнениях:

scala> a == E.User
res9: Boolean = true

Если JPA возвращает только строку, и нет пути к ней.Тогда я думаю, что лучший вариант - либо преобразовать значение в строку и сопоставить строку со строкой, либо обновить строку до значения Val и сравнить Val.Смешивание этих типов не сработает для сравнения, если вы не реализуете какое-то расширение для метода equals, и это сложно.

15 голосов
/ 05 августа 2010

Расширяя ответ Томаса, если вы используете сравнение с ответвлением, может быть более подходящим использование сопоставления с образцом:

object Role extends Enumeration {
   val User = MyValue("User")
   val Admin = MyValue("Admin")

   def MyValue(name: String): Value with Matching = 
         new Val(nextId, name) with Matching

   // enables matching against all Role.Values
   def unapply(s: String): Option[Value] = 
      values.find(s == _.toString)

   trait Matching {
      // enables matching against a particular Role.Value
      def unapply(s: String): Boolean = 
            (s == toString)
   }
}

Затем вы можете использовать это следующим образом:

def allowAccess(role: String): Boolean = role match {
   case Role.Admin() => true
   case Role.User() => false
   case _ => throw ...
}

или

// str is a String
str match { 
   case Role(role) => // role is a Role.Value
   case Realm(realm) => // realm is a Realm.Value
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...