Updated enums.md

Privo authored
revision 51cc8b9a4d396e37a90921f4c7371a41b706e72c
enums
# 5.12. 열거형 (Enums) - 5%

러스트의 `enum`은 몇 개 중 하나가 될 수 있는 자료
100%

Rust의 `enum`은 여러 개의 변종(Variant) 중 하나의 데이터
를 표현하는 타입입니다.

```rust
enum Message {
Quit,
ChangeColor(i32, i32, i32),
Move { x: i32, y: i32 },
Write(String),
}
```

각각은 그것과 연관된 자료를 선택적으로 가질 수 있습니다. The syntax for
defining variants resembles the syntaxes used to define structs: you can
have variants with no data (like unit-like structs), variants with named
data, and variants with unnamed data (like tuple structs). Unlike
separate struct definitions, however, an `enum` is a single type. A
value of the enum can match any of the variants. For this reason, an
enum is sometimes called a ‘sum type’: the set of possible values of the
enum is the sum of the sets of possible values for each variant.

We use the `::` syntax to use the name of each variant: they’re scoped by the name
of the `enum` itself. This allows both of these to work:

```rust
# enum Message {
# Move { x: i32, y: i32 },
# }
let x: Message = Message::Move { x: 3, y: 4 };

enum BoardGameTurn {
Move { squares: i32 },
Pass,
}

let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };
```

Both variants are named `Move`, but since they’re scoped to the name of
the enum, they can both be used without conflict.

A value of an enum type contains information about which variant it is,
in addition to any data associated with that variant. This is sometimes
referred to as a ‘tagged union’, since the data includes a ‘tag’
indicating what type it is. The compiler uses this information to
enforce that you’re accessing the data in the enum safely. For instance,
you can’t simply try to destructure a value as if it were one of the
possible variants:

```rust,ignore
fn process_color_change(msg: Message) {
let Message::ChangeColor(r, g, b) = msg; // compile-time error
}
```

Not supporting these operations may seem rather limiting, but it’s a limitation
which we can overcome. There are two ways: by implementing equality ourselves,
or by pattern matching variants with [`match`][match] expressions, which you’ll
learn in the next section. We don’t know enough about Rust to implement
equality yet, but we’ll find out in the [`traits`][traits] section.

[match]: match.html
[if-let]: if-let.html
[traits]: traits.html

# Constructors as functions

An enum’s constructors can also be used like functions. For example
의 변종은 자신과 연관된 데이터를 선택적으로 가질 수 있습니다. 변종을 정의하는 데 사용되는 문법은 구조체를 정의하는 데 사용되는 문법과 유사합니다: (단위 유사 구조체처럼) 데이터를 가지지 않는 변종을 정의할 수도 있고, 데이터에 이름을 붙여 정의할 수도 있고, (튜플 구조체처럼) 이름 없는 데이터를 정의할 수도 있습니다. 그러나 분리된 구조체 정의와는 달리 `enum`은 한 가지의 타입만을 갖습니다. enum의 값은 변종 중 하나와 대응되면 됩니다. 이러한 연유로 종종 enum은 'sum type'이라 불리기도 합니다: enum의 가능한 값들의 집합이 각각의 변종의 가능한 값의 집합의 합이기 때문입니다.

각각의 변종을 사용하기 위해서 `::` 문법을 사용합니다: 변종은 `enum` 범위 그 자체에 귀속되어 있습니다. 이는 아래 두 가지를 가능하게 합니다.

```rust
# enum Message {
# Move { x: i32, y: i32 },
# }
let x: Message = Message::Move { x: 3, y: 4 };

enum BoardGameTurn {
Move { squares: i32 },
Pass,
}

let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };
```

두 변종은 `Move`라는 이름은 같으나, enum 범위에 귀속되어 있으므로 충돌 없이 사용할 수 있습니다.

enum 타입의 값은 변종에 연관된 데이터와 더불어 어느 변종인지에 관한 정보를 포함하고 있습니다. 데이터가 타입이 무엇인지를 말해주는 'tag'를 포함하고 있으므로 이것을 때때로 'tagged union'이라 부릅니다. 컴파일러는 이 정보를 이용하여 enum 내에 있는 데이터에 안전하게 접근하게끔 만듭니다. 예로 값이 변종 중 하나인 것처럼 가정하여 단순하게 값을 해체(destructure)하려 시도할 수 없습니다:

```rust,ignore
fn process_color_change(msg: Message) {
let Message::ChangeColor(r, g, b) = msg; // compile-time error
}
```

위와 같은 연산을 지원하지 않는 것이 상당히 제한적이라고 보이지만 충분히 극복할 수 있는 제한입니다. 이를 극복하는데 두 가지 방법이 있습니다: 우리 스스로 동등성(equality)을 구현하는 방법과 다음 부문에서 배우게 될 [`패턴 정합`][match](pattern match) 을 이용하는 방법입니다. 동등성을 구현하는 데 있어 아직은 Rust를 잘 모르지만, [`트레잇`][traits] 부문에서 알게 될 겁니다.

[match]: match.html
[if-let]: if-let.html
[traits]: traits.html

# 함수형 생성자 (Constructors as functions)

enum의 생성자는 함수처럼 사용됩니다. 에
:

```rust
# enum Message {
# Write(String),
# }
let m = Message::Write("Hello, world".to_string());
```

Is the same as위는 아래와 같음

```rust
# enum Message {
# Write(String),
# }
fn foo(x: String) -> Message {
Message::Write(x)
}

let x = foo("Hello, world".to_string());
```

This is not immediately useful to us, but when we get to
[`closures`][closures], we’ll talk about passing functions as arguments to
other functions. For example, with [`iterators`][iterators], we can do this
to convert a vector of `String`s into a vector of `Message::Write`s
이것은 우리에게 지금 당장 유용하지는 않습니다. 그러나 [`클로저`][closures]를 배우게 될 때, 함수를 인자로 하여 다른 함수로 전달하는 것에 관해 말할 것입니다. 예로 [`반복자`][iterators]를 가지고서 `String` 벡터를 `Message::Write` 벡터로 전환하는데 함수를 다른 함수로 전달할 수 있습니다:

```rust
# enum Message {
# Write(String),
# }

let v = vec!["Hello".to_string(), "World".to_string()];

let v1: Vec = v.into_iter().map(Message::Write).collect();
```

[closures]: closures.html
[iterators]: iterators.html