enum
enum (Enums)
enum은 각 값에 이름이 붙어 있는 정수 값들의 집합이에요. 예를 들어 볼게요.
enum Color
Red
Green
Blue
end
참고: 이 페이지는 Crystal의 enum에 대한 내용이에요. C enum에 대해서는 C bindings enum을 참고하세요.
enum은 enum 키워드 뒤에 이름을 적어 정의하고, 몸통(body)에 값들을 담아요. 값은 0에서 시작해 하나씩 증가합니다. 기본 값을 덮어쓸 수도 있어요.
enum Color
Red # 0
Green # 1
Blue = 5 # overwritten to 5
Yellow # 6 (5 + 1)
end
enum의 각 상수는 enum의 타입을 가져요.
Color::Red # :: Color
기저(underlying) 값을 얻으려면 그 위에 value를 호출해요.
Color::Green.value # => 1
값의 타입은 기본적으로 Int32인데, 바꿀 수 있어요.
enum Color : UInt8
Red
Green
Blue
end
Color::Red.value # :: UInt8
기저 타입으로는 정수 타입만 허용됩니다.
모든 enum은 Enum에서 상속받아요.
본문
플래그 enum (Flags enums)
enum은 @[Flags] 어노테이션으로 표시할 수 있어요. 이 어노테이션은 기본 값들을 바꿉니다.
@[Flags]
enum IOMode
Read # 1
Write # 2
Async # 4
end
@[Flags] 어노테이션은 첫 번째 상수의 값이 1이 되게 하고, 이후 상수는 2를 곱해가며 만들게 해요.
암묵적 상수 None과 All이 이 enum들에 자동으로 추가되는데, None은 값 0을, All은 모든 상수의 "or"된 값(|)을 가져요.
IOMode::None.value # => 0
IOMode::All.value # => 7
추가로, 일부 Enum 메서드는 @[Flags] 어노테이션을 확인해요. 예를 들어:
puts(Color::Red) # prints "Red"
puts(IOMode::Write | IOMode::Async) # prints "Write, Async"
정수에서 enum 만들기 (Enums from integers)
enum은 정수에서 만들 수 있어요.
puts Color.new(1) # => prints "Green"
enum의 상수에 대응하지 않는 값도 허용됩니다. 값의 타입은 여전히 Color지만, 출력하면 기저 값을 얻을 수 있어요.
puts Color.new(10) # => prints "10"
이 메서드는 주로 C의 정수를 Crystal의 enum으로 바꾸기 위한 것이에요.
술어 메서드 (Predicate methods)
enum은 각 멤버에 대해 술어 메서드(predicate method)를 자동으로 정의합니다. 메서드 이름은 String#underscore를 사용해 만들어져요.
참고: 일반 enum의 경우
==로 동등성을 비교해요. 플래그 enum의 경우includes?를 호출합니다.
예를 들어:
enum Color
Red
Green
Blue
end
color = Color::Blue
color.red? # => false
color.blue? # => true
@[Flags]
enum IOMode
Read
Write
Async
end
mode = IOMode::Read | IOMode::Async
mode.read? # => true
mode.write? # => false
mode.async? # => true
메서드 (Methods)
클래스나 구조체처럼, enum에도 메서드를 정의할 수 있어요.
enum ButtonSize
Sm
Md
Lg
def label
case self
in .sm? then "small"
in .md? then "medium"
in .lg? then "large"
end
end
end
ButtonSize::Sm.label # => "small"
ButtonSize::Lg.label # => "large"
클래스 변수는 허용되지만 인스턴스 변수는 허용되지 않아요.
사용하기 (Usage)
메서드 매개변수가 enum 타입 제약을 가질 때는, enum 상수나 심볼 중 하나를 받을 수 있어요. 심볼은 enum 상수로 자동 캐스팅되며, 캐스팅에 실패하면 컴파일 타임 오류가 발생합니다.
def paint(color : Color)
puts "Painting using the color #{color}"
end
paint Color::Red
paint :red # automatically casts to `Color::Red`
paint :yellow # Error: expected argument #1 to 'paint' to match a member of enum Color
이 자동 캐스팅은 case 문에는 적용되지 않아요. case 문에서 enum을 쓰려면 case enum values를 참고하세요.
더 알아보기 (Learn more)
- Crystal 공식 문서 - Enums
- C bindings enum — C enum 바인딩
- case — case 문에서 enum 값 다루기