[SCALA] 어떻게 형태 보증 된 열거 유형을 모델링하기 위해?
SCALA어떻게 형태 보증 된 열거 유형을 모델링하기 위해?
자바는이 같은 스칼라 형태 보증 된 열거이 없습니다. 관련 상수의 집합을 감안할 때, 어떻게 그 상수를 대표하는 스칼라에서 가장 좋은 방법이 될 것입니다?
해결법
-
==============================
1.http://www.scala-lang.org/docu/files/api/scala/Enumeration.html
http://www.scala-lang.org/docu/files/api/scala/Enumeration.html
사용 예
object Main extends App { object WeekDay extends Enumeration { type WeekDay = Value val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value } import WeekDay._ def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun) WeekDay.values filter isWorkingDay foreach println }
-
==============================
2.나는 (당신은뿐만 아니라 경우에 객체를 사용할 수 있습니다) skaffman에 의해 스칼라 문서에서 복사 한 예는 위의 연습에 제한 유틸리티입니다라고해야합니다.
나는 (당신은뿐만 아니라 경우에 객체를 사용할 수 있습니다) skaffman에 의해 스칼라 문서에서 복사 한 예는 위의 연습에 제한 유틸리티입니다라고해야합니다.
자바 열거를 닮은 가장 가까운 무언가를 얻기 위해 (즉 재치있는 toString 및 위해 valueOf 방법과 - 아마도 당신이 데이터베이스에 열거 값을 지속하는) 당신은 그것을 조금 수정해야합니다. 당신은 skaffman의 코드를 사용했다면 :
WeekDay.valueOf("Sun") //returns None WeekDay.Tue.toString //returns Weekday(2)
다음과 같은 선언을 사용하는 반면 :
object WeekDay extends Enumeration { type WeekDay = Value val Mon = Value("Mon") val Tue = Value("Tue") ... etc }
좀 더 합리적인 결과를 얻을 수 있습니다 :
WeekDay.valueOf("Sun") //returns Some(Sun) WeekDay.Tue.toString //returns Tue
-
==============================
3.일을 여러 가지 방법이 있습니다.
일을 여러 가지 방법이 있습니다.
1) 문자를 사용합니다. 그것은 상징이 예상되는 비 문자 수락하지 제외하고,하지만, 당신에게 모든 유형의 안전을 제공하지 않습니다. 난 단지 완성도를 위해 여기를 언급하고있다. 다음은 사용의 예입니다 :
def update(what: Symbol, where: Int, newValue: Array[Int]): MatrixInt = what match { case 'row => replaceRow(where, newValue) case 'col | 'column => replaceCol(where, newValue) case _ => throw new IllegalArgumentException } // At REPL: scala> val a = unitMatrixInt(3) a: teste7.MatrixInt = / 1 0 0 \ | 0 1 0 | \ 0 0 1 / scala> a('row, 1) = a.row(0) res41: teste7.MatrixInt = / 1 0 0 \ | 1 0 0 | \ 0 0 1 / scala> a('column, 2) = a.row(0) res42: teste7.MatrixInt = / 1 0 1 \ | 0 1 0 | \ 0 0 0 /
2) 클래스 열거를 사용 :
object Dimension extends Enumeration { type Dimension = Value val Row, Column = Value }
또는, 당신은 직렬화하거나 표시해야하는 경우 :
object Dimension extends Enumeration("Row", "Column") { type Dimension = Value val Row, Column = Value }
이것은 다음과 같이 사용할 수 있습니다 :
def update(what: Dimension, where: Int, newValue: Array[Int]): MatrixInt = what match { case Row => replaceRow(where, newValue) case Column => replaceCol(where, newValue) } // At REPL: scala> a(Row, 2) = a.row(1) <console>:13: error: not found: value Row a(Row, 2) = a.row(1) ^ scala> a(Dimension.Row, 2) = a.row(1) res1: teste.MatrixInt = / 1 0 0 \ | 0 1 0 | \ 0 1 0 / scala> import Dimension._ import Dimension._ scala> a(Row, 2) = a.row(1) res2: teste.MatrixInt = / 1 0 0 \ | 0 1 0 | \ 0 1 0 /
불행하게도, 모든 경기가 차지되는 것을 보장하지 않습니다. 내가 경기를 행 또는 열을 넣어 잊어 버린 경우, 스칼라 컴파일러는 나에게 경고 않았을 것이다. 그래서 얻을 수 있지만만큼, 나에게 어떤 종류의 안전을 제공합니다.
3) 케이스 제품 :
sealed abstract class Dimension case object Row extends Dimension case object Column extends Dimension
내가 경기에 케이스를두면 이제 컴파일러는 나에게 경고합니다 :
MatrixInt.scala:70: warning: match is not exhaustive! missing combination Column what match { ^ one warning found
그것은 거의 같은 방법으로 사용되는, 심지어 가져 오기를 필요로하지 않습니다
scala> val a = unitMatrixInt(3) a: teste3.MatrixInt = / 1 0 0 \ | 0 1 0 | \ 0 0 1 / scala> a(Row,2) = a.row(0) res15: teste3.MatrixInt = / 1 0 0 \ | 0 1 0 | \ 1 0 0 /
어느 경우 객체 대신에 열거를 사용하는 이유 당신은 다음, 궁금 할 것이다. 사실, 경우 객체는 장점에게 같은 여기에 많은 시간을 가지고 않습니다. 열거 클래스는, 비록 그러한 요소 반환 (스칼라 2.8 반복자), 반복자지도 flatMap, 필터링 등의 많은 수집 방법을 가지고
이 답변은 본질적으로 내 블로그에이 문서에서 선택한 부분이다.
-
==============================
4.이름이 열거 형을 선언하는 약간 덜 자세한 방법 :
이름이 열거 형을 선언하는 약간 덜 자세한 방법 :
object WeekDay extends Enumeration("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat") { type WeekDay = Value val Sun, Mon, Tue, Wed, Thu, Fri, Sat = Value } WeekDay.valueOf("Wed") // returns Some(Wed) WeekDay.Fri.toString // returns Fri
물론 여기에서 문제는 이름과 발을 같은 줄에 선언 된 경우 수행하는 것이 더 쉽습니다 동기화 이름과 발스의 순서를 유지해야한다는 것입니다.
-
==============================
5.당신은 예를 들어, 대신 열거의 밀봉 추상 클래스를 사용할 수 있습니다 :
당신은 예를 들어, 대신 열거의 밀봉 추상 클래스를 사용할 수 있습니다 :
sealed abstract class Constraint(val name: String, val verifier: Int => Boolean) case object NotTooBig extends Constraint("NotTooBig", (_ < 1000)) case object NonZero extends Constraint("NonZero", (_ != 0)) case class NotEquals(x: Int) extends Constraint("NotEquals " + x, (_ != x)) object Main { def eval(ctrs: Seq[Constraint])(x: Int): Boolean = (true /: ctrs){ case (accum, ctr) => accum && ctr.verifier(x) } def main(args: Array[String]) { val ctrs = NotTooBig :: NotEquals(5) :: Nil val evaluate = eval(ctrs) _ println(evaluate(3000)) println(evaluate(3)) println(evaluate(5)) } }
-
==============================
6.단지 enumeratum을 발견했다. 그것은 꽤 놀라운과 더 잘 알려진 아니에요 똑같이 놀라운!
단지 enumeratum을 발견했다. 그것은 꽤 놀라운과 더 잘 알려진 아니에요 똑같이 놀라운!
-
==============================
7.주변의 모든 옵션에 대한 광범위한 연구를 수행 한 후 "열거는"스칼라에서, 나는 다른 StackOverflow의 스레드에서이 도메인의 훨씬 더 전체 개요를 기록했다. 그것은 내가 JVM 클래스 / 객체 초기화 순서 문제를 해결 한 "밀봉 특성 + 경우 개체"패턴에 대한 솔루션이 포함되어 있습니다.
주변의 모든 옵션에 대한 광범위한 연구를 수행 한 후 "열거는"스칼라에서, 나는 다른 StackOverflow의 스레드에서이 도메인의 훨씬 더 전체 개요를 기록했다. 그것은 내가 JVM 클래스 / 객체 초기화 순서 문제를 해결 한 "밀봉 특성 + 경우 개체"패턴에 대한 솔루션이 포함되어 있습니다.
-
==============================
8.도티 (스칼라 3) 지원 기본 열거있을 것이다. 여기와 여기에 확인하십시오.
도티 (스칼라 3) 지원 기본 열거있을 것이다. 여기와 여기에 확인하십시오.
-
==============================
9.스칼라에서 그것은 https://github.com/lloydmeta/enumeratum 매우 편안
스칼라에서 그것은 https://github.com/lloydmeta/enumeratum 매우 편안
프로젝트 예제와 문서와 정말 좋은
그냥 자신의 문서에서이 예는해야 할 의향이 있습니다
import enumeratum._ sealed trait Greeting extends EnumEntry object Greeting extends Enum[Greeting] { /* `findValues` is a protected method that invokes a macro to find all `Greeting` object declarations inside an `Enum` You use it to implement the `val values` member */ val values = findValues case object Hello extends Greeting case object GoodBye extends Greeting case object Hi extends Greeting case object Bye extends Greeting } // Object Greeting has a `withName(name: String)` method Greeting.withName("Hello") // => res0: Greeting = Hello Greeting.withName("Haro") // => java.lang.IllegalArgumentException: Haro is not a member of Enum (Hello, GoodBye, Hi, Bye) // A safer alternative would be to use `withNameOption(name: String)` method which returns an Option[Greeting] Greeting.withNameOption("Hello") // => res1: Option[Greeting] = Some(Hello) Greeting.withNameOption("Haro") // => res2: Option[Greeting] = None // It is also possible to use strings case insensitively Greeting.withNameInsensitive("HeLLo") // => res3: Greeting = Hello Greeting.withNameInsensitiveOption("HeLLo") // => res4: Option[Greeting] = Some(Hello) // Uppercase-only strings may also be used Greeting.withNameUppercaseOnly("HELLO") // => res5: Greeting = Hello Greeting.withNameUppercaseOnlyOption("HeLLo") // => res6: Option[Greeting] = None // Similarly, lowercase-only strings may also be used Greeting.withNameLowercaseOnly("hello") // => res7: Greeting = Hello Greeting.withNameLowercaseOnlyOption("hello") // => res8: Option[Greeting] = Some(Hello)
from https://stackoverflow.com/questions/1321745/how-to-model-type-safe-enum-types by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 게으른 발은 무엇입니까? (0) | 2019.11.02 |
---|---|
[SCALA] 스파크 DataFrame에서 중첩 열 삭제 (0) | 2019.11.02 |
[SCALA] "암시"스칼라 ID는 무엇입니까? (0) | 2019.11.02 |
[SCALA] 독립 RDD의 병렬로 여러 개의 파일을 처리 (0) | 2019.11.02 |
[SCALA] 스칼라에서 인쇄 배열 (0) | 2019.11.02 |