У меня есть перечисление в scala, сопоставленное строкам в JPA. Для более удобного кодирования я определял неявные преобразования между ними. Поэтому теперь я могу определить значение val person.role = "User", - person.role - это тип перечисления "User" a String, чтобы преобразование. Но когда я пытаюсь сравнить эти два, я всегда получаю false, потому что def equals (arg0: Any) : Boolean занимает Any, поэтому никакого преобразования не запускается. Мне нужно некоторое явное преобразование, но мой план состоял в том, чтобы упустить это, как вы думаете, это лучшая практика | здесь самое лучшее решение?
Сравнение строк и перечислений
Ответ 1
 Value("User") Value("User") имеет тип 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, и это сложно.
Ответ 2
Развернувшись на ответ Томаса, если вы используете сравнение с веткой, использование шаблонов может быть более подходящим:
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
   ...
}
