Enums¶
Note
This page is for Crystal enums. For C enums, see C bindings enum.
An enum is a set of integer values, where each value has an associated name. For example:
enum Color
Red
Green
Blue
end
An enum is defined with the enum
keyword, followed by its name. The enum's body contains the values. Values start with the value 0
and are incremented by one. The default value can be overwritten:
enum Color
Red # 0
Green # 1
Blue = 5 # overwritten to 5
Yellow # 6 (5 + 1)
end
Each constant in the enum has the type of the enum:
Color::Red # :: Color
To get the underlying value, you invoke value
on it:
Color::Green.value # => 1
The type of the value is Int32
by default, but can be changed:
enum Color : UInt8
Red
Green
Blue
end
Color::Red.value # :: UInt8
Only integer types are allowed as the underlying type.
All enums inherit from Enum.
Flags enums¶
An enum can be marked with the @[Flags]
annotation. This changes the default values:
@[Flags]
enum IOMode
Read # 1
Write # 2
Async # 4
end
The @[Flags]
annotation makes the first constant's value be 1
, and successive constants are multiplied by 2
.
Implicit constants, None
and All
, are automatically added to these enums, where None
has the value 0
and All
has the "or"ed value of all constants.
IOMode::None.value # => 0
IOMode::All.value # => 7
Additionally, some Enum
methods check the @[Flags]
annotation. For example:
puts(Color::Red) # prints "Red"
puts(IOMode::Write | IOMode::Async) # prints "Write, Async"
Enums from integers¶
An enum can be created from an integer:
puts Color.new(1) # => prints "Green"
Values that don't correspond to an enum's constants are allowed: the value will still be of type Color
, but when printed you will get the underlying value:
puts Color.new(10) # => prints "10"
This method is mainly intended to convert integers from C to enums in Crystal.
Methods¶
Just like a class or a struct, you can define methods for enums:
enum Color
Red
Green
Blue
def red?
self == Color::Red
end
end
Color::Red.red? # => true
Color::Blue.red? # => false
Class variables are allowed, but instance variables are not.
Usage¶
When a method parameter has an enum type restriction, it accepts either an enum constant or a symbol. The symbol will be automatically cast to an enum constant, raising a compile-time error if casting fails.
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
The same automatic casting does not apply to case statements. To use enums with case statements, see case enum values.