Merge changes from maxnuke into master

sarojaba authored
revision 16d8eb0b08d2288806e1541766c654f2ec34ca85
patterns
# 5.14. 패턴 (Patterns) - 80%

패턴은 러스트에서 흔하게 나타납니다. [변수 바인딩][bindings], [정합][match], 그 외에서 사용합니다. 그럼 이러한 패턴들을 한번 잽싸게 살펴봅시다!

[bindings]: variable-bindings.html
[match]: match.html

간단한 복습: 문자 match로 문자 그대로 선언하며, `_`는 '어떤 경우에도'를 나타냅니다.

```rust
let x = 1;

match x {
1 => println!("one"),
2 => println!("two"),
3 => println!("three"),
_ => println!("anything"),
}
```

`one`을 출력합니다.

# Multiple patterns

다수의 패턴을 `|`로 묶을 수 있습니다:

```rust
let x = 1;

match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}
```

`one or two`를 출력합니다.

# Destructuring

[`구조체`][struct]와 같이, 사용하는 데이터 타입이 복합적이라면 패턴 내에서 디스트럭처(destructure)할 수 있습니다.

```rust
struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { x, y } => println!("({},{})", x, y),
}
```

[struct]: structs.html

`:`를 써서 값에 다른 이름을 줄 수 있습니다.

```rust
struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { x: x1, y: y1 } => println!("({},{})", x1, y1),
}
```

만약 값들 중 몇가지에만 관심이 있다면, 다른 나머지를 써줄 필요가 없습니다:

```rust
struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { x, .. } => println!("x is {}", x),
}
```

`x is 0`을 출력합니다.

첫번째에만 가능한 것이 아니라, 어떤 종류의 멤버도 매치 가능합니다:

```rust
struct Point {
x: i32,
y: i32,
}

let origin = Point { x: 0, y: 0 };

match origin {
Point { y, .. } => println!("y is {}", y),
}
```

`y is 0`을 출력합니다.

'디스트럭처링(destructuring)'은 [튜플][tuples]이나 [열거형][enums] 등, 어떤 복잡한 데이터 타입에도 작용합니다.

[tuples]: primitive-types.html#tuples
[enums]: enums.html

# Ignoring bindings

You can use `_` in a pattern to disregard the type and value.
For example, here’s a `match` against a `Result`
타입 이나 값을 무시하기 하기 위해서 패턴 안에 `_` 을 넣을 수 있습니다.
예를 들어, `Result` 타입의 `match`가 있다고 합시다
:

```rust
# let some_value: Result = Err("There was an error");
match some_value {
Ok(value) => println!("got a value: {}", value),
Err(_) => println!("an error occurred"),
}
```

In the first arm, we bind the value inside the `Ok` variant to `value`. But
in the `Err` arm, we use `_` to disregard the specific error, and just print
a general error message.

`_` is valid in any pattern that creates a binding. This can be useful to
ignore parts of a larger structure
첫 번째 경우에는, `Ok`안에 있는 값을 `value`에 묶었습니다.
`Err`인 경우에는 , 특정 에러를 무시하기 위해 `_`를 썼습니다 , 그리고
일반적인 에러 메세지를 출력합니다 .

`_` 은 바인딩(binding)이 일어 나는 모든 패턴에 대해서는 유효합니다
큰 구조체에서 일부를 무시할 때 유용합니다
:

```rust
fn coordinate() -> (i32, i32, i32) {
// generate and return some sort of triple tuple
# (1, 2, 3)
}

let (x, _, z) = coordinate();
```

Here, we bind the first and last element of the tuple to여기서,튜플에서 중간 요소를 무시하고 첫번째 요소와 마지막요소를 각각 `x` and `z`, but
ignore the middle element.

Similarly, you can use `..` in a pattern to disregard multiple values
에 묶었습니다.

비슷하게,다수의 변수를 무시하기 위해서 패턴내에 `..`을 넣을 수 있습니다
.

```rust
enum OptionalTuple {
Value(i32, i32, i32),
Missing,
}

let x = OptionalTuple::Value(5, -2, 3);

match x {
OptionalTuple::Value(..) => println!("Got a tuple!"),
OptionalTuple::Missing => println!("No such luck."),
}
```

This prints `Got a tuple!`이 출력됩니다.

# ref and ref mut

[참조][ref]를 얻고 싶다면, `ref` 키워드를 사용합니다.

```rust
let x = 5;

match x {
ref r => println!("Got a reference to {}", r),
}
```

`Got a reference to 5`를 출력합니다.

[ref]: references-and-borrowing.html

`match`의 `r` 안에는 `&i32` 타입을 가지고 있습니다. `ref` 키워드는 패턴 내에서 참조를 _생성한다는_ 뜻입니다. 만약 변경 가능한(mutable) 참조를 사용한다면, `ref mut`로 써줄 수 있습니다:

```rust
let mut x = 5;

match x {
ref mut mr => println!("Got a mutable reference to {}", mr),
}
```

# Ranges

값의 범위를 `...`로 묶을 수 있습니다:

```rust
let x = 1;

match x {
1 ... 5 => println!("one through five"),
_ => println!("anything"),
}
```

`one through five`를 출력하게 됩니다.

범위는 정수형과 `char`형에 가장 널리 쓰입니다:

```rust
let x = '💅';

match x {
'a' ... 'j' => println!("early letter"),
'k' ... 'z' => println!("late letter"),
_ => println!("something else"),
}
```

`something else`를 출력하게 되겠죠.

# Bindings

`@`를 써서 변수를 이름에 바인딩할 수 있습니다:

```rust
let x = 1;

match x {
e @ 1 ... 5 => println!("got a range element {}", e),
_ => println!("anything"),
}
```

`got a range element 1`를 출력합니다. 데이터 구조 일부분에 복잡한 작업을 하려고 할 때에 유용합니다:

```rust
#[derive(Debug)]
struct Person {
name: Option,
}

let name = "Steve".to_string();
let mut x: Option = Some(Person { name: Some(name) });
match x {
Some(Person { name: ref a @ Some(_), .. }) => println!("{:?}", a),
_ => {}
}
```

`Some("Steve")`를 출력합니다: 내부의 `name`을 `a`에 대입했습니다.

`@`를 `|`와 함께 사용한다면, 각 부분들이 모두 이름에 대입된 것을 재확인시켜주어야만 합니다.

```rust
let x = 5;

match x {
e @ 1 ... 5 | e @ 8 ... 10 => println!("got a range element {}", e),
_ => println!("anything"),
}
```

# Guards

`if`를 통해 매치 가드(match guards)를 사용할 수 있습니다:

```rust
enum OptionalInt {
Value(i32),
Missing,
}

let x = OptionalInt::Value(5);

match x {
OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"),
OptionalInt::Value(..) => println!("Got an int!"),
OptionalInt::Missing => println!("No such luck."),
}
```

`Got an int!`를 출력합니다.

`if`를 다수의 패턴과 사용한다면, `if`는 양쪽 모두에 적용됩니다:

```rust
let x = 4;
let y = false;

match x {
4 | 5 if y => println!("yes"),
_ => println!("no"),
}
```

`5`에만 적용되는게 아니라, `4 | 5` 모두에 `if`가 적용되기 때문에, `no`를 출력합니다. `if`가 우선순위가 되어 다음과 같이 작동하는 것입니다:
```text
(4 | 5) if y => ...
```

이렇게가 아니라요:

```text
4 | (5 if y) => ...
```

# Mix and Match

휴! 당신이 어떻게 쓰느냐에 따라 짜 맞출수 있는(mixed and matched) 아주 많은 매치 방법들이 있습니다:

```rust,ignore
match x {
Foo { x: Some(ref name), y: None } => ...
}
```

패턴은 아주 강력합니다. 잘 사용해보세요.