Updated patterns.md

SoonBin authored
revision 82ccbeac359f76fa3ee900647fb641d2a8b60df6
patterns
# 5.15. 패턴 (Patterns) - 0%

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

[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`를 출력합니다.

# 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"),
}
```

# Ignoring variants

열거형(enum)을 매칭할때는, `..`를 사용해 변수의 세세한 값이나 타입을 무시할 수 있습니다.

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

let x = OptionalInt::Value(5);

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

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

# 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) => ...
```

# 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),
}
```

# 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

# Mix and Match

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

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

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