홈강좌Rust 입문·중급 47편 중 24편째
Rust 열거형 — 정해진 몇 가지 중 하나를 타입으로 만든다
Rust 열거형(enum)은 신호등의 빨강·노랑·초록처럼 정해진 몇 가지 중 하나인 값을 타입으로 만든다. Light::Red 처럼 타입 이름과 :: 로 고르고, 없는 이름을 쓰면 E0599 가 난다. 경우마다 다른 데이터를 붙일 수도 있다.
01 enum 으로 경우를 늘어놓는다
#[derive(Debug, PartialEq)]
enum Light {
Red,
Yellow,
Green,
}
fn main() {
let now = Light::Red;
println!("{now:?}");
for light in [Light::Red, Light::Yellow, Light::Green] {
let can_go = light == Light::Green;
println!("{light:?}: can go = {can_go}");
}
} Compiling light v0.1.0 (~/projects/light)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.22s
Running `target/debug/light`
Red
Red: can go = false
Yellow: can go = false
Green: can go = trueenum Light { Red, Yellow, Green }은 새 타입Light를 정의한다. 중괄호 안의 이름 하나하나를 경우(variant)라 한다.- 값은
Light::Red처럼 타입 이름 뒤에::로 고른다.Light타입의 값은 셋 중 반드시 하나다. 넷째 값은 없다. #[derive(Debug, PartialEq)]는 22편의derive에 기능을 하나 더한 것이다.Debug는{:?}로 찍기,PartialEq는==로 비교하기다.
신호등 상태를 문자열 "red" 나 숫자 0 으로 다룰 수도 있다. 하지만 그러면 "rde" 같은 오타나 7 같은 엉뚱한 값도 들어간다. 열거형이면 그런 값은 아예 만들 수 없다.
02 없는 경우를 쓰면 E0599
#[derive(Debug)]
enum Light {
Red,
Yellow,
Green,
}
fn main() {
let now = Light::Blue;
println!("{now:?}");
}error[E0599]: no variant or associated item named `Blue` found for enum `Light` in the current scope
--> src/main.rs:9:22
|
2 | enum Light {
| ---------- variant or associated item `Blue` not found for this enum
...
9 | let now = Light::Blue;
| ^^^^ variant or associated item not found in `Light`- 무엇 — enum
Light에Blue라는 경우(variant)가 없다. - 어디 — 9번째 줄의
Light::Blue. 2번째 줄의 정의도 함께 짚는다....는 사이의 줄을 줄였다는 표시다. - 고치는 법 —
help:는 없다. 정의에 있는Red·Yellow·Green중 하나를 쓰거나, 정말 필요하면 정의에Blue를 더한다.
03 실습 — 경우마다 데이터 붙이기
경우에 값을 붙일 수도 있다. 도형을 예로 들면, 원은 반지름 하나, 사각형은 가로·세로 둘, 점은 아무것도 필요 없다.
#[derive(Debug)]
enum Shape {
Circle(f64),
Rect(f64, f64),
Dot,
}
fn main() {
let shapes = [Shape::Circle(1.5), Shape::Rect(3.0, 4.0), Shape::Dot];
for s in shapes {
println!("{s:?}");
}
}Circle(1.5)
Rect(3.0, 4.0)
DotShape::Circle(1.5) 처럼 경우 이름 뒤 괄호에 값을 넣어 만든다. 구조체(22편)로 이것을 나타내려면 반지름·가로·세로 칸을 모두 두고 안 쓰는 칸을 비워야 하는데, Rust 에는 빈 칸이 없다. 열거형은 경우마다 필요한 값만 갖는다.
실제로 돌리면 위 세 줄 앞에 경고(warning: field 0 is never read)가 30줄쯤 나온다. 붙인 값을 한 번도 꺼내 쓰지 않았다는 뜻이다. 값을 꺼내려면 "지금 어느 경우인가" 를 따져야 하는데, 그 일을 하는 것이 다음 편의 match 다. 다음 편에서 이 Shape 로 넓이를 구하면 경고도 사라진다. 그 전에 enum-basic 에 Off(꺼짐) 경우를 더해 보자. for 의 배열에도 넣어야 한다.