Julia Language
열거 형
수색…
통사론
- @enum EnumType val = 1 val val
- :상징
비고
때로는 각 인스턴스가 다른 유형 (종종 싱글 톤 불변 유형 ) 인 열거 형을 갖는 것이 유용합니다. 이것은 유형 안정성에 중요 할 수 있습니다. 특성은 일반적으로이 패러다임으로 구현됩니다. 그러나 이로 인해 컴파일 시간 오버 헤드가 추가로 발생합니다.
열거 형 정의
열거 형 은 가능한 값의 유한 목록 중 하나를 보유 할 수있는 유형 입니다. Julia에서 열거 형은 일반적으로 "열거 형"이라고합니다. 예를 들어, 일주일 중 7 일, 12 개월, 표준 52 카드 데크 의 네 가지 슈트 또는 기타 유사한 상황을 설명하기 위해 enum 유형을 사용할 수 있습니다.
우리는 열거 형을 정의하여 표준 52 카드 덱의 수트와 랭크를 모델링 할 수 있습니다. @enum
매크로는 enum 유형을 정의하는 데 사용됩니다.
@enum Suit ♣ ♦ ♥ ♠
@enum Rank ace=1 two three four five six seven eight nine ten jack queen king
여기에는 Suit
과 Rank
두 가지 유형이 정의됩니다. 값이 실제로 예상되는 유형인지 확인할 수 있습니다.
julia> ♦
♦::Suit = 1
julia> six
six::Rank = 6
각 수트와 랭크는 숫자와 연관되어 있습니다. 기본적으로이 숫자는 0부터 시작합니다. 따라서 두 번째 수트 인 다이아몬드에는 1이 할당되었습니다. Rank
의 경우 하나에서 번호를 시작하는 것이 더 적합 할 수 있습니다. 이것은 a =1
주석이있는 ace
의 정의에 주석을 ace
얻을 수있었습니다.
열거 형에는 평등 (및 실제로 신원) 및 비교 기능과 같은 많은 기능이 있습니다.
julia> seven === seven
true
julia> ten ≠ jack
true
julia> two < three
true
다른 불변 형의 값과 마찬가지로, 열거 형의 값은 해시되고 Dict
저장 될 수 있습니다.
Rank
및 Suit
필드가있는 Card
유형을 정의하여이 예를 완성 할 수 있습니다.
immutable Card
rank::Rank
suit::Suit
end
따라서 우리는 다음과 같은 카드를 만들 수 있습니다.
julia> Card(three, ♣)
Card(three::Rank = 3,♣::Suit = 0)
그러나 열거 형은 자체 convert
메서드도 함께 제공되므로 실제로 수행 할 수 있습니다.
julia> Card(7, ♠)
Card(seven::Rank = 7,♠::Suit = 3)
7
을 직접 Rank
로 변환 할 수 Rank
생성자는 기본적으로 작동합니다.
우리는이 카드를 만들 때 통용적 인 설탕을 정의하고자 할 것입니다. 암시 적 곱셈은이를 수행하는 편리한 방법을 제공합니다. 밝히다
julia> import Base.*
julia> r::Int * s::Suit = Card(r, s)
* (generic function with 156 methods)
그리고
julia> 10♣
Card(ten::Rank = 10,♣::Suit = 0)
julia> 5♠
Card(five::Rank = 5,♠::Suit = 3)
다시 한 번 내장 된 convert
함수를 이용합니다.
경량 열거 형으로 기호 사용
@enum
매크로는 대부분의 유스 케이스에 매우 유용하지만 일부 유스 케이스에서는 과도 할 수있다. @enum
단점은 @enum
과 같습니다.
- 새로운 유형을 만듭니다.
- 확장하기가 조금 더 어렵다.
- 변환, 열거 및 비교와 같은 기능이 제공되며 일부 응용 프로그램에서는 불필요 할 수 있습니다
더 가벼운 대안을 원할 경우 Symbol
유형을 사용할 수 있습니다. 심볼은 내부 문자열입니다 . 그들은 문자열의 경우처럼 문자의 시퀀스를 나타내지 만 숫자와 고유하게 연관됩니다. 이 고유 한 연관성은 빠른 기호 평등 비교를 가능하게합니다.
이번에는 Symbol
필드를 사용하여 Card
유형을 다시 구현할 수 있습니다.
const ranks = Set([:ace, :two, :three, :four, :five, :six, :seven, :eight, :nine,
:ten, :jack, :queen, :king])
const suits = Set([:♣, :♦, :♥, :♠])
immutable Card
rank::Symbol
suit::Symbol
function Card(r::Symbol, s::Symbol)
r in ranks || throw(ArgumentError("invalid rank: $r"))
s in suits || throw(ArgumentError("invalid suit: $s"))
new(r, s)
end
end
우리는 내부 생성자를 구현하여 생성자에 전달 된 잘못된 값을 확인합니다. @enum
유형을 사용하는 예제와 달리 Symbol
에는 임의의 문자열이 포함될 수 있으므로 우리가 받아 들인 Symbol
의 종류에주의해야합니다. 여기서 단락 조건 연산자의 사용에 유의하십시오.
이제 우리는 예상대로 Card
객체를 생성 할 수 있습니다.
julia> Card(:ace, :♦)
Card(:ace,:♦)
julia> Card(:nine, :♠)
Card(:nine,:♠)
julia> Card(:eleven, :♠)
ERROR: ArgumentError: invalid rank: eleven
in Card(::Symbol, ::Symbol) at ./REPL[17]:5
julia> Card(:king, :X)
ERROR: ArgumentError: invalid suit: X
in Card(::Symbol, ::Symbol) at ./REPL[17]:6
Symbol
의 주요 이점은 런타임 확장 성입니다. 런타임에 (예를 들어) :eleven
새로운 순위로 :eleven
을 받아들이 려한다면 push!(ranks, :eleven)
실행하기 만하면됩니다. 이러한 런타임 확장 성은 @enum
유형에서는 가능하지 않습니다.