2010-08-04 5 views
10

JPA의 문자열에 매핑 된 스칼라 열거 형이 있습니다. 보다 편한 코딩을 위해, 나는 그들 사이의 암시적인 변환을 정의했다. 그래서 이제 값 val person.role = "User"을 정의 할 수 있습니다. - person.role은 열거 형 문자열이므로 변환이 있습니다. 그러나이 둘을 비교하려고 시도하면 def equals (arg0: Any) : BooleanAny이 걸리므로 전환이 트리거되지 않으므로 항상 거짓이됩니다. 나는 명시적인 변환이 필요하다. 그러나 나의 계획은 그것을 생략 할 수 있어야했다. 당신은 베스트 프랙티스라고 생각 하는가 | 가장 깨끗한 해결책은 여기에 있습니까?문자열과 열거 비교

+0

'열거'및 '값'에이 매핑을 사용하고 있습니까? – Thomas

+0

@ 토마스 예 스칼라의'scala.Enumeration'과'scala.Enumeration.Value'를 사용하고 있습니다 – coubeatczech

+0

비교를위한 문맥/유스 케이스는 무엇입니까? 패턴 일치는 더 나은 솔루션을 제공 할 수 있지만 실제로 달성하려는 대상에 따라 달라집니다. –

답변

16

EnumerationValue("User")Val입니다. 그리고 그 구현은 equals 값의 문자열 이름을 비교하지 않는다고 생각합니다. 이 작업을 수행하는 한 가지 방법은 이름이 일치하면 true를 반환하도록 자신의 EnumerationVal을 만드는 것입니다.

하지만 내 코드에서는 JPA가 아니라 항상 문자열을 MyEnumeration.Value으로 변환합니다. 당신은 예외가 문자열이 열거에있는 이름과 일치하지 않는 경우, withName를 사용할 때 것을

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

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

참고 :이 같은 것들로 간단합니다.

그런 다음 항상 비교에 열거 필드를 사용 :

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

는 JPA는 문자열을 반환하는 경우, 그리고 주위에 방법이 없습니다. 그렇다면 가장 좋은 방법은 값을 문자열로 변환하고 문자열을 문자열로 일치 시키거나 문자열을 Val로 업그레이드하고 Val을 비교하는 것입니다. equals 메소드에 대한 확장 기능을 구현하지 않으면 이러한 유형을 혼합하여 비교할 수 없으며 이는 까다 롭습니다. 당신이 더 적합 할 수 있습니다 패턴 매칭을 사용하여 지점에 대한 비교를 사용하는 경우, 토마스의 대답에 확장

13

:

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