Merge changes from master into djKooks

djKooks authored
revision dd2bca49ac9ec02af8165833d444ad11afdab6d6
closures
# 5.23. 클로저 (Closures) - 10%

러스트는 익명함수 또한 사가끔 내부 함수와 _자유 변수_(_free variable_)(내부 함수 안에서 정의되지 않은 변수)를 둘러싼 함수가 유용할 때가 있습니다. 익명함수는 (한 영역 밖으로는 닫혀있기 때문에) 클로저라 불리는 연결된 영역을 가지고 있습자유 변수는 내부 함수와 인접한 영역(scope)에서 갖고 오고, 이 함수를 사용할 때 '닫힙니다(결정됩니다)'. 그렇기 때문에 이런 함수를 '클로저(closure)'라 부릅니다. 러스트는 이것을 정말 잘 지원하고 있습니다.
실제로 살펴보도록 하죠.

## Syntax문법

다음과 같은 클로저가 있습니다:

```rust
let plus_one = |x: i32| x + 1;

assert_eq!(2, plus_one(1));
```

우리는 `plus_one`에 바인딩을 만들어, 클로저에 그것을 할당했습니다. 클로저의 인수(arguments)는 파이프(`|`) 사이에, 몸체(body)에는 표현식을 씁니다. `x + 1` 이 해당됩니다.
`{ }`를 기억하신다면, 우리는가 표현식(expression)이라는 것을 기억하시나요? 이걸로 여러 줄로 된 클로저 또한 만들 수 있습니다.

```rust
let plus_two = |x| {
let mut result: i32 = x;

result += 1;
result += 1;

result
};

assert_eq!(4, plus_two(2));
```

클로저가 `fn`으로 정의되는 일반 함수와 약간 다르다는 것을 눈치채셨을 겁니다. 첫번째로 클로저가 받는 인수나 반환값의 타입을 명시해줄 필요가 없다는 것입니다.
물론 명시해 줄 수 있습니다:

```rust
let plus_one = |x: i32| -> i32 { x + 1 };

assert_eq!(2, plus_one(1));
```

그렇지만 그렇게 할 필요가 없습니다. 왜 그럴까요? 기본적으로, 사람이 보다 편하기 위해서입니다. 일반 함수가 문서나 타입 추론에 도움이 되게 하기 위해 타입들을 모두 명시하는 반면에, 클로저는 익명함수로써 error-at-a-distance 종류의 문제를 일으키지 않기 때문에 좀처럼 그렇게 하지 않습니다.

두번째는 이 비슷하지만, 조금은 다르다는 것입니다. 간단한 비교를 해보죠.

```rust
fn plus_one_v1 (x: i32 ) -> i32 { x + 1 }
let plus_one_v2 = |x: i32 | -> i32 { x + 1 };
let plus_one_v3 = |x: i32 | x + 1 ;
```

조금 다르긴 하지만,들은래도 비슷합니다.

## 클로저와 영역

클로저(Closure)라 불리는 이유는 그들의 영역에 닫혀있기(close) 때문입
그 환경(environment)

클로저의 환경은 그것을 둘러싼 영역의 변수는 물론 바인딩까지도 포함합
니다.
다음을 보면:

```rust
let num = 5;
let plus_num = |x: i32| x + num;

assert_eq!(10, plus_num(5));
```

`plus_num` 이라는 클로저는
This closure, `plus_num`, refers to a `let` binding in its scope: `num`. More
specifically, it borrows the binding. If we do something that would conflict
with that binding, we get an error. Like this one:
, 본인이 속한 영역에서 `let` 을 통해 바인딩되어 있는 `num`을 참조합니다. 정확히 말하면, 그 바인딩을 빌리게 됩니다. 만약 우리가 바인딩 된 이것을 가지고 뭔가 하게 되면 충돌이 발생하고, 이런 에러가 납니다:


```rust,ignore
let mut num = 5;
let plus_num = |x: i32| x + num;

let y = &mut num;
```

Which errors with이런 에러 메시지도 같이요:

```text
error: cannot borrow `num` as mutable because it is also borrowed as immutable
let y = &mut num;
^~~
note: previous borrow of `num` occurs here due to use in closure; the immutable
borrow prevents subsequent moves or mutable borrows of `num` until the borrow
ends
let plus_num = |x| x + num;
^~~~~~~~~~~
note: previous borrow ends here
fn main() {
let mut num = 5;
let plus_num = |x| x + num;

let y = &mut num;
}
^
```

A verbose yet helpful error message! As it says, we can’t take a mutable borrow
on `num` because the closure is already borrowing it. If we let the closure go
out of scope, we can
장황하긴 하지만 유용한 에러 메시지에서 볼 수 있듯이, 우리는 `num`을 변화 가능한 형태로 빌릴 수 없는데, 이유는 클로저가 이미 `num`을 빌리는 중이기 때문입니다. 그렇기 때문에 클로저의 영역 바깥에서나 `num`을 빌릴 수 있습니다:

```rust
let mut num = 5;
{
let plus_num = |x: i32| x + num;

} // plus_num goes out of scope, borrow of num ends

let y = &mut num;
```

If your closure requires it, however, Rust will take ownership and move
the environment instead. This doesn’t work
그러나 클로저가 소유권을 달라고 하면 Rust는 소유권을 가져가고 대신 환경을 옮겨(move)버립니다. 다음 코드는 동작하지 않습니다:

```rust,ignore
let nums = vec![1, 2, 3];

let takes_nums = || nums;

println!("{:?}", nums);
```

We get this error에러메시지는 이렇습니다:

```text
note: `nums` moved into closure environment here because it has type
`[closure(()) -> collections::vec::Vec]`, which is non-copyable
let takes_nums = || nums;
^~~~~~~
```

`Vec` has ownership over its contents, and therefore, when we refer to it
in our closure, we have to take ownership of `nums`. It’s the same as if we’d
passed `nums` to a function that took ownership of it.

## `move` closures

We can force our closure to take ownership of its environment with the `move`
keyword:

```rust
let num = 5;

let owns_num = move |x: i32| x + num;
```

Now, even though the keyword is `move`, the variables follow normal move semantics.
In this case, `5` implements `Copy`, and so `owns_num` takes ownership of a copy
of `num`. So what’s the difference?

```rust
let mut num = 5;

{
let mut add_num = |x: i32| num += x;

add_num(5);
}

assert_eq!(10, num);
```

So in this case, our closure took a mutable reference to `num`, and then when
we called `add_num`, it mutated the underlying value, as we’d expect. We also
needed to declare `add_num` as `mut` too, because we’re mutating its
environment.

If we change to a `move` closure, it’s different:

```rust
let mut num = 5;

{
let mut add_num = move |x: i32| num += x;

add_num(5);
}

assert_eq!(5, num);
```

We only get `5`. Rather than taking a mutable borrow out on our `num`, we took
ownership of a copy.

Another way to think about `move` closures: they give a closure its own stack
frame. Without `move`, a closure may be tied to the stack frame that created
it, while a `move` closure is self-contained. This means that you cannot
generally return a non-`move` closure from a function, for example.

But before we talk about taking and returning closures, we should talk some more
about the way that closures are implemented. As a systems language, Rust gives
you tons of control over what your code does, and closures are no different.

## Closure implementation
는 자신 내부 요소들에 대해 소유권을 갖기 때문에, 클로저에서 이를 참조하려면 `nums`의 소유권을 얻을 필요가 있습니다. 말하자면 `nums`를 함수에서 사용하려면 `nums`의 소유권도 같이 전달하는 것과 같죠.


## `move` 클로저

`move` 키워드로 클로저가 자신의 환경의 소유권을 가져가도록 할 수 있습니다:

```rust
let num = 5;

let owns_num = move |x: i32| x + num;
```

이 경우는 `move` 키워드가 있는데도 변수는 그냥 일반적인 이동을 따릅니다. 이 경우 `5`가 `Copy`되고, `owns_num`는 복사된 `num`의 소유권을 가져갑니다. 차이점이 뭘까요?

```rust
let mut num = 5;

{
let mut add_num = |x: i32| num += x;

add_num(5);
}

assert_eq!(10, num);
```

이번에는 클로저가 변경가능한 `num`의 리퍼런스를 가져가기 때문에 `add_num`를 호출하면, `num` 값이 변경될 겁니다. 환경이 변하기 때문에 `add_num` 을 `mut`로 선언해야 합니다.

`move` 클로저로 바꾸면 이렇게 달라집니다:

```rust
let mut num = 5;

{
let mut add_num = move |x: i32| num += x;

add_num(5);
}

assert_eq!(5, num);
```

이렇게 하면 그냥 `5`가 나옵니다. 변경가능한 `num`을 빌려오는 대신에 그냥 `num`을 복사한 값의 소유권을 갖고 온 거죠.

이렇게도 생각해 볼까요. `move` 클로저는 클로저에게 자기만의 스택 공간을 줍니다. `move` 가 없으면 클로저는 생성될 때의 스택에 묶이겠죠. 말하자면 `move` 클로저는 컨테이너라고 할 수 있습니다. 즉 예를 들어서, 일반적으로 함수 내에서 `move` 클로저가 아닌 클로저를 반환하는 것은 불가능합니다.

클로저를 취하고 반환하는 법을 더 자세히 다루기 전에, 클로저를 구현하는 방식에 대해서 더 다뤄 봅시다. 시스템 언어인 러스트는 코드로 통제할 수 있는 부분이 엄청나게 많고, 이는 클로저도 마찬가지입니다.

## Closure implementation 클로저 구현

러스트에서 클로저를 구현하는 방식은 다른 언어와는 약간 다르다. 그들은 traits를 위한 효과적 문법 설탕이다. 이에 대해 더 알고 싶다면 traits chapter를 살펴보거나 그 전에 trait-object 챕터를 읽어보도록 해라.

Rust’s implementation of closures is a bit different than other languages. They
are effectively syntax sugar for traits. You’ll want to make sure to have read
the [traits chapter][traits] before this one, as well as the chapter on [trait
objects][trait-objects].

[traits]: traits.html
[trait-objects]: trait-objects.html

다 읽었나? 좋아.
Got all that? Good.

클로저를 이해하는 방식의 키는 조금 낯설 수도 있다. `foo()`와 같은 방식으로 `()`를 사용하여 함수를 호출하게 되는데, 이는 오버로드 가능한 연산자이다. 이런 방식은 다른 모든 것에도 동일하게 적용된다.( 역주: `()`라는 오퍼레이션이 오버로드 되어 함수 호출자가 되는 것과 동일 방식) 러스트에서는 trait 시스템을 연산자 오버로드에 사용한다. 함수를 호출하는 것도 다른지 않다. 우리는 이를 위해 세 개의 traits를 사용한다.
The key to understanding how closures work under the hood is something a bit
strange: Using `()` to call a function, like `foo()`, is an overloadable
operator. From this, everything else clicks into place. In Rust, we use the
trait system to overload operators. Calling functions is no different. We have
three separate traits to overload with:

```rust
# mod foo {
pub trait Fn : FnMut {
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

pub trait FnMut : FnOnce {
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

pub trait FnOnce {
type Output;

extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
# }
```

몇 가지 차이점들이 눈에 띄지만, 가장 중요한 것은 `self`:`Fn`이 `&self`를 취하고, `FnMut`이 `&mut self`를 취하며 `FnOnce`는 `self`를 취한다는 점이다. 이 세 가지 형태의 `self`는 모두 함수 호출 문법으로 사용된다. 하지만 우리는 이것을 하나보다는 세개의 traits으로 나누어 구현했다. 이것이 우리가 사용할 수 있는 클로저에 많은 권한을 부여한다.
You’ll notice a few differences between these traits, but a big one is `self`:
`Fn` takes `&self`, `FnMut` takes `&mut self`, and `FnOnce` takes `self`. This
covers all three kinds of `self` via the usual method call syntax. But we’ve
split them up into three traits, rather than having a single one. This gives us
a large amount of control over what kind of closures we can take.

클로저 문법인 `|| {}`이 이 세개의 traits를 위한 요소이다. 러스트는 환경을 위한 구조체를 만들고, 적절한 trait을 `impl` 하여, 사용하게 된다.
The `|| {}` syntax for closures is sugar for these three traits. Rust will
generate a struct for the environment, `impl` the appropriate trait, and then
use it.

## Taking closures as arguments

## Taking closures as arguments 클로저의 인자 값 취하기

이제 우리는 클로저가 traits임을 알게 됐으니, 이를 통해 클로저로 인자 값을 받거나 리턴하는 방법도 알게 됐다. 그냥 다른 trait처럼 사용하면 된다!

Now that we know that closures are traits, we already know how to accept and
return closures: just like any other trait!

이것은 또한 우리가 static 혹은 dynamic 한 방식을 취할 수 있음을 뜻한다. 첫 째로, 호출할 수 있는 함수를 만들어 호출하고 리턴하는 함수를 만들어보자. 이렇게 :
This also means that we can choose static vs dynamic dispatch as well. First,
let’s write a function which takes something callable, calls it, and returns
the result:

```rust
fn call_with_one(some_closure: F) -> i32
where F : Fn(i32) -> i32 {

some_closure(1)
}

let answer = call_with_one(|x| x + 2);

assert_eq!(3, answer);
```
우리는 클로저 `|x| x + 2`를 `call_with_one`으로 전달한다. 이것은 보다시피: 클로저를 호출하며, `1`을 인자로 주는 것이다.
We pass our closure, `|x| x + 2`, to `call_with_one`. It just does what it
suggests: it calls the closure, giving it `1` as an argument.

`call_with_one`이란 서명을 좀더 깊게 살펴보자.
Let’s examine the signature of `call_with_one` in more depth:

```rust
fn call_with_one(some_closure: F) -> i32
# where F : Fn(i32) -> i32 {
# some_closure(1) }
```

우리는 하나의 인자를 취하고, 타입은 `F`다. 또한 우리는 `i32`를 반환한다. 이 부분은 그닥 중요하진 않고 다음으로 넘어가자:
We take one parameter, and it has the type `F`. We also return a `i32`. This part
isn’t interesting. The next part is:

```rust
# fn call_with_one(some_closure: F) -> i32
where F : Fn(i32) -> i32 {
# some_closure(1) }
```

`Fn`이 trait이기 때문에, 이를 통해 우리의 제네릭의 범위를 정할 수 있다. 이번 예에서, 우리의 클로저는 `i32`를 인자로 취하고 `i32`를 반환하기에 제네릭의 범위를 `Fn(i32) -> i32`로 사용한다.
Because `Fn` is a trait, we can bound our generic with it. In this case, our closure
takes a `i32` as an argument and returns an `i32`, and so the generic bound we use
is `Fn(i32) -> i32`.

여기에는 또 하나의 키 포인트가 있다: 우리가 trait과 함께 제네릭의 범위를 정하기에, 이것은 다형성을 갖게 되므로, 우리는 static dispatch 를 클로저에서 사용할 수 있다. 이건 훌륭하다! 많은 언어들이, 클로저는 본질적으로 heap 할당을 받고, dynamic dispatch 가 되게 된다. 러스트에서는 클로저 환경을 stack에 할당할 수 있고, static한 방식으로 dispatch 호출을 할 수 있다. 이는 많은 iterator와 그들의 adapter들에서 클로저를 인자로 받는 방식으로 많이 사용된다.
There’s one other key point here: because we’re bounding a generic with a
trait, this will get monomorphized, and therefore, we’ll be doing static
dispatch into the closure. That’s pretty neat. In many languages, closures are
inherently heap allocated, and will always involve dynamic dispatch. In Rust,
we can stack allocate our closure environment, and statically dispatch the
call. This happens quite often with iterators and their adapters, which often
take closures as arguments.

당연하게 우리가 dynamic dispatch를 하는 것도 가능하다. trait object를 이렇게 다루면 된다:
Of course, if we want dynamic dispatch, we can get that too. A trait object
handles this case, as usual:

```rust
fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 {
some_closure(1)
}

let answer = call_with_one(&|x| x + 2);

assert_eq!(3, answer);
```

이번에 우리는 trait object를 `&Fn`으로 취한다. 그리고 우리의 클로저를 `call_with_one`의 인자로 전할 때 `&||`로 참조하여 보낸다.
Now we take a trait object, a `&Fn`. And we have to make a reference
to our closure when we pass it to `call_with_one`, so we use `&||`.

## Function pointers and closures

## Function pointers and closures 함수 포인터와 클로저

함수 포인터는 환경없는 클로저의 형태이다. 그렇기에, 우리는 함수 포인터를 클로저를 인자로 기대하는 어떤 함수에도 전달할 수 있고 동작할 것이다:

A function pointer is kind of like a closure that has no environment. As such,
you can pass a function pointer to any function expecting a closure argument,
and it will work:

```rust
fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 {
some_closure(1)
}

fn add_one(i: i32) -> i32 {
i + 1
}

let f = add_one;

let answer = call_with_one(&f);

assert_eq!(2, answer);
```

이번 예제에서, 우리는 `f`라는 중간 매개가 필요하다고 제약하진 않고, 함수 이름을 사용해도 문제 없다 :
In this example, we don’t strictly need the intermediate variable `f`,
the name of the function works just fine too:

```ignore
let answer = call_with_one(&add_one);
```

## Returning closures
클로저를 반환하기

다양한 상황에서 함수 스타일의 코드에서 클로저를 반환하는 매우 일반적이다. 만약 당신이 클로저를 반한하고자 한다면, 에러를 볼 수 있을 것이다. 처음에는, 낯설게 느껴지겠지만 이해할 수 있을 것이다. 클로저를 함수에서 반환하는 방법을 알아보자:

It’s very common for functional-style code to return closures in various
situations. If you try to return a closure, you may run into an error. At
first, it may seem strange, but we’ll figure it out. Here’s how you’d probably
try to return a closure from a function:

```rust,ignore
fn factory() -> (Fn(i32) -> i32) {
let num = 5;

|x| x + num
}

let f = factory();

let answer = f(1);
assert_eq!(6, answer);
```

위의 코드는 다음과 같은 긴 에러를 보여준다:
This gives us these long, related errors:

```text
error: the trait `core::marker::Sized` is not implemented for the type
`core::ops::Fn(i32) -> i32` [E0277]
fn factory() -> (Fn(i32) -> i32) {
^~~~~~~~~~~~~~~~
note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time
fn factory() -> (Fn(i32) -> i32) {
^~~~~~~~~~~~~~~~
error: the trait `core::marker::Sized` is not implemented for the type `core::ops::Fn(i32) -> i32` [E0277]
let f = factory();
^
note: `core::ops::Fn(i32) -> i32` does not have a constant size known at compile-time

let f = factory();
^
```

함수에서 뭔가를 반환하는 경우, 러스트는 타입의 사이즈를 알아야 할 필요가 있다. 하지만 `Fn`이 trait이 된 이후, 이는 많은 다양한 형태의 크기의 사이즈를 갖을 수 있게 됐다: 많은 다양한 형태가 `Fn`으로 구현될 수 있다. 간단한 방법은 사이즈로 뭔가 전해주기 위해, 참조를 취하는 것이고, 참조의 사이즈는 알고 있다. 그래서 다음과 같이 작성해보자:
In order to return something from a function, Rust needs to know what
size the return type is. But since `Fn` is a trait, it could be various
things of various sizes: many different types can implement `Fn`. An easy
way to give something a size is to take a reference to it, as references
have a known size. So we’d write this:

```rust,ignore
fn factory() -> &(Fn(i32) -> i32) {
let num = 5;

|x| x + num
}

let f = factory();

let answer = f(1);
assert_eq!(6, answer);
```

하지만 또 다른 에러가 보이게 된다:
But we get another error:

```text
error: missing lifetime specifier [E0106]
fn factory() -> &(Fn(i32) -> i32) {
^~~~~~~~~~~~~~~~~
```

맞아! 우리가 참조를 취했기에 이에 대한 시한을 설정할 필요가 있다. 하지만 우리 `factory()` 함수는 아무 인자도 없기에 생략하면 발로 차이게 되는 것이다. 어떤 시한을 우리가 선택할 수 있을까? `'static`:
Right. Because we have a reference, we need to give it a lifetime. But
our `factory()` function takes no arguments, so elision doesn’t kick in
here. What lifetime can we choose? `'static`:

```rust,ignore
fn factory() -> &'static (Fn(i32) -> i32) {
let num = 5;

|x| x + num
}

let f = factory();

let answer = f(1);
assert_eq!(6, answer);
```

하지만 또 다른 에러가 난다:
But we get another error:

```text
error: mismatched types:
expected `&'static core::ops::Fn(i32) -> i32`,
found `[closure :7:9: 7:20]`
(expected &-ptr,
found closure) [E0308]
|x| x + num
^~~~~~~~~~~

```
이번 에러는 우리에게 `&'static Fn(i32) -> i32` 가 아니라 `[closure :7:9: 7:20]`를 다루고 있다고 알려준다. 잠깐, 뭐라?
This error is letting us know that we don’t have a `&'static Fn(i32) -> i32`,
we have a `[closure :7:9: 7:20]`. Wait, what?

이유는 각 클로저가 그들 고유의 `struct`환경을 갖고 `Fn`을 함께 구현된 코드를 생산하기 때문에, 이 타입들은 익명이 된다. 이들은 고유하게 해당 클로저를 위해서만 존재한다. 그래서 러스트는 `closure `라고 보여주고, 이는 자동으로 생성된 이름이다.
Because each closure generates its own environment `struct` and implementation
of `Fn` and friends, these types are anonymous. They exist just solely for
this closure. So Rust shows them as `closure `, rather than some
autogenerated name.

그렇다고 하더라도 왜 클로저는 `&'static Fn`이 아닐까? 글쎄, 우리가 이전에 토의했 듯, 클로저는 그들의 환경을 대여한다. 그리고 이번 케이스에서 우리의 환경은 stack 할당된 `num` 변수에 바인딩 되어 있는 `5`를 기반하고 있다. 그래서 시한은 stack frame에 달려있다. (역주:stack이 해제되면 자동으로 소멸) 그래서 우리가 해당 클로저를 반환하게 되면, 함수 호출이 끝나고, stack frame이 소멸되고, 우리의 클로저 환경은 쓰레기 메모리에 위치하게 될 것이다!
But why doesn’t our closure implement `&'static Fn`? Well, as we discussed before,
closures borrow their environment. And in this case, our environment is based
on a stack-allocated `5`, the `num` variable binding. So the borrow has a lifetime
of the stack frame. So if we returned this closure, the function call would be
over, the stack frame would go away, and our closure is capturing an environment
of garbage memory!

그래서 어떻게 해야 할까? 이는 거의 될 것 같다:
So what to do? This _almost_ works:

```rust,ignore
fn factory() -> Box i32> {
let num = 5;

Box::new(|x| x + num)
}
# fn main() {
let f = factory();

let answer = f(1);
assert_eq!(6, answer);
# }
```

우리는 trait object를 `Box` 포장한 `Fn`을 통해 사용한다. 여기에 마지막 문제가 있다:
We use a trait object, by `Box`ing up the `Fn`. There’s just one last problem:

```text
error: closure may outlive the current function, but it borrows `num`,
which is owned by the current function [E0373]
Box::new(|x| x + num)
^~~~~~~~~~~
```

우리는 아직 기원 stack frame의 참조를 하고 있다. 마지막 수정을 해보자:
We still have a reference to the parent stack frame. With one last fix, we can
make this work:

```rust
fn factory() -> Box i32> {
let num = 5;

Box::new(move |x| x + num)
}
# fn main() {
let f = factory();

let answer = f(1);
assert_eq!(6, answer);
# }
```

내부 클로저를 `move Fn`으로 만듬으로, 우리는 새로운 stack frame을 클로저에게 주어줬다. `Box`포장을 통해, 우리는 사이즈를 알 수 있게 해줬고, 이는 stack frame에서 빠져나오게 한다.

By making the inner closure a `move Fn`, we create a new stack frame for our
closure. By `Box`ing it up, we’ve given it a known size, and allowing it to
escape our stack frame.
crates-and-modules
# 5.25. 크레이트들과(Crate) 모듈들(Module) - 0%

프로젝트가 방대해지기 시작하면서, 좋은 소프트웨어 엔지니어들은 그를 작은 조각으로 나누는데 신경쓰기 시작했고, 이게 협업하기에 적합하다. 또한 어떤 기능들을 private하게 할 것인지, public하게 할 것인지처럼 잘 정의된 interface 도 중요하다. 이러한 종류의 것들을 용이하게 할 수 있도록, 러스트는 모듈 시스템을 지원한다.
When a project starts getting large, it’s considered good software
engineering practice to split it up into a bunch of smaller pieces, and then
fit them together. It’s also important to have a well-defined interface, so
that some of your functionality is private, and some is public. To facilitate
these kinds of things, Rust has a module system.

# Basic terminology: Crates and Modules
기본 용어 : Crate들과 Module들

러스트는 모듈 시스템과 관련해 `crate`와 `module`이라는 독특한 두 용어를 사용한다. crate는 '라이브러리' 혹은 '패키지' 와 같은 의미를 갖는 언어이다. "Cargo"가 러스트의 패키지 매니저 도구의 이름으로 정해졌기에: 당신은 당신이 만든 crate들을 카고를 통해 다른 사람들에게 보낼 수 있다. Crate들은 프로젝트에 따라 실행가능 형태 혹은 라이브러리가 될 수 있다.

Rust has two distinct terms that relate to the module system: ‘crate’ and
‘module’. A crate is synonymous with a ‘library’ or ‘package’ in other
languages. Hence “Cargo” as the name of Rust’s package management tool: you
ship your crates to others with Cargo. Crates can produce an executable or a
library, depending on the project.

모든 crate들은 각자가 소유한 코드를 포함하는 암시적인 *root module*이다. 당신은 root module 이하에 sub-module들을 Tree처럼 정의할 수 있다. module은 당신의 코드들을 crate로 나눌 수 있도록 한다.
Each crate has an implicit *root module* that contains the code for that crate.
You can then define a tree of sub-modules under that root module. Modules allow
you to partition your code within the crate itself.

예로, *단어* crate를 만들어보려는데, 이는 다양한 단어를 서로 다른 언어로 반환할 것이다. 간단하게, 우리는 'greetings'와 'farewells' 두 단어를 영어와 일본어로 넣어놓을 것이다. 우리가 만들 모듈의 레이아웃:
As an example, let’s make a *phrases* crate, which will give us various phrases
in different languages. To keep things simple, we’ll stick to ‘greetings’ and
‘farewells’ as two kinds of phrases, and use English and Japanese (日本語) as
two languages for those phrases to be in. We’ll use this module layout:

```text
+-----------+
+---| greetings |
| +-----------+
+---------+ |
+---| english |---+
| +---------+ | +-----------+
| +---| farewells |
+---------+ | +-----------+
| phrases |---+
+---------+ | +-----------+
| +---| greetings |
| +----------+ | +-----------+
+---| japanese |--+
+----------+ |
| +-----------+
+---| farewells |
+-----------+
```

이번 예제에서, `phrases`(단어)는 우리 crate의 이름이다. 다른 것들은 모듈들이다. 당신이 보다시피 이는 crate *root* : `phrases` 자신에서 뻗어져나오는 트리 구조를 갖는다.
In this example, `phrases` is the name of our crate. All of the rest are
modules. You can see that they form a tree, branching out from the crate
*root*, which is the root of the tree: `phrases` itself.

이제 우리가 계획했듯, 모듈들을 코드로 옮겨보자. 먼저 새 crate를 Cargo로 만든다:
Now that we have a plan, let’s define these modules in code. To start,
generate a new crate with Cargo:

```bash
$ cargo new phrases
$ cd phrases
```

당신이 기억하듯, 이는 간단한 프로젝트를 우리에게 만들어준다:
If you remember, this generates a simple project for us:

```bash
$ tree .
.
├── Cargo.toml
└── src
└── lib.rs

1 directory, 2 files
```

`src/lib.rs`는 우리의 root crate이고 우리의 다이어그램에서 `phrases`와 대응된다.
`src/lib.rs` is our crate root, corresponding to the `phrases` in our diagram
above.

# Defining Modules
모듈 정의하기

우리의 모듈 각각을 정의하기 위해, 우리는 `mod`라는 키워드를 사용한다. `src/lib.rs`를 만들어보자. 다음과 같다:

To define each of our modules, we use the `mod` keyword. Let’s make our
`src/lib.rs` look like this:

```rust
mod english {
mod greetings {
}

mod farewells {
}
}

mod japanese {
mod greetings {
}

mod farewells {
}
}
```

`mod`키워드 뒤에, 당신은 모듈의 이름을 지어줬다. 모듈 네임들은 `lower_snake_case` 와 같은 러스트에 정의된 규칙을 따른다. 각각의 모듈들의 내용은 중괄호(`{}`) 속에 들어간다.
After the `mod` keyword, you give the name of the module. Module names follow
the conventions for other Rust identifiers: `lower_snake_case`. The contents of
each module are within curly braces (`{}`).

`mod`와 함께, 당신은 sub-`mod`들도 선언할 수 있다. 우리는 서브-모듈들을 더블콜론(`::`)을 통해 참조할 수 있게 한다: 우리의 네 중첩된 모듈들은 `english::greetings`, `english::farewells`, `japanese::greetings`, 와 `japanese::farewells`이다. 왜냐면, 이들은 자신의 모체 모듈의 네임스페이스 하에 있기 때문에, 이름들은 충돌나지 않는다: 그들의 이름이 `greetings`로 같더라도 `english::greetings`와 `japanese::greetings`로 사용할 수 있다.

Within a given `mod`, you can declare sub-`mod`s. We can refer to sub-modules
with double-colon (`::`) notation: our four nested modules are
`english::greetings`, `english::farewells`, `japanese::greetings`, and
`japanese::farewells`. Because these sub-modules are namespaced under their
parent module, the names don’t conflict: `english::greetings` and
`japanese::greetings` are distinct, even though their names are both
`greetings`.

우리가 crate에 `main()` 함수를 만들지 않았고, `lib.rs`라고 이름지었기 때문에 Cargo는 이 crate를 라이브러리로 만든다:
Because this crate does not have a `main()` function, and is called `lib.rs`,
Cargo will build this crate as a library:

```bash
$ cargo build
Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
$ ls target/debug
build deps examples libphrases-a7448e02a0468eaa.rlib native
```

`libphrases-hash.rlib`는 crate의 컴파일된 결과물이다. 우리가 전에 crate를 다른 crate에서 어떻게 사용하는지 봤으니, 이를 다수의 파일로 나눠보도록 하자.
`libphrases-hash.rlib` is the compiled crate. Before we see how to use this
crate from another crate, let’s break it up into multiple files.

# Multiple file crates
다수의 파일 crate들

다양한 crate가 하나의 파일에 있으면, 이 파일들은 매우 방대해진다. 이를 다수의 파일들로 나누는게 더 쉬울 수가 있고, 러스트는 이를 두 가지 방법으로 지웒나다.

If each crate were just one file, these files would get very large. It’s often
easier to split up crates into multiple files, and Rust supports this in two
ways.

모듈을 다음과 같이 선언하는 대신에:
Instead of declaring a module like this:

```rust,ignore
mod english {
// contents of our module go here
}
```

우리는 다음과 같이 모듈을 선언할 수 있다:
We can instead declare our module like this:

```rust,ignore
mod english;
```

이렇게 하면, 러스트는 `english.rs`라는 파일이나 `english/mod.rs`파일과 내용을 찾을 것이라고 기대한다.
If we do that, Rust will expect to find either a `english.rs` file, or a
`english/mod.rs` file with the contents of our module.

이 파일들과 관련되 말하고 주의할 점은, 당신은 모듈을 다시 선언할 필요가 없다: 이는 이미 `mod`선언과 함께 초기화 된다.
Note that in these files, you don’t need to re-declare the module: that’s
already been done with the initial `mod` declaration.

이런 두 가지 기법을 사용해, 우리는 crate들을 두 개의 디렉토리와 일곱개의 파일로 나눌 수 있다.
Using these two techniques, we can break up our crate into two directories and
seven files:

```bash
$ tree .
.
├── Cargo.lock
├── Cargo.toml
├── src
│ ├── english
│ │ ├── farewells.rs
│ │ ├── greetings.rs
│ │ └── mod.rs
│ ├── japanese
│ │ ├── farewells.rs
│ │ ├── greetings.rs
│ │ └── mod.rs
│ └── lib.rs
└── target
└── debug
├── build
├── deps
├── examples
├── libphrases-a7448e02a0468eaa.rlib
└── native
```

`src/lib.rs`는 우리의 루트 crate이고 다음과 같은 내용을 갖는다:
`src/lib.rs` is our crate root, and looks like this:

```rust,ignore
mod english;
mod japanese;
```

이 두 선언은 러스트에게 우리의 설정에 따라 `src/english.rs`와 `src/japanese.rs`를 찾거나, `src/english/mod.rs`와 `src/japanese/mod.rs`를 찾으라고 말하는 것이다,. 이번 경우에는, 우리의 모듈이 서브 모듈들을 갖기에, 우리는 두 번째 방식을 취한다. `src/english/mod.rs`와 `src/japanese/mod.rs`는 다음과 같은 내용이다:
These two declarations tell Rust to look for either `src/english.rs` and
`src/japanese.rs`, or `src/english/mod.rs` and `src/japanese/mod.rs`, depending
on our preference. In this case, because our modules have sub-modules, we’ve
chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
like this:

```rust,ignore
mod greetings;
mod farewells;
```

또 한번, 이 선언들은 러스트에게 `src/english/greetings.rs`과 `src/japanese/greetings.rs` 혹은 `src/english/farewells/mod.rs` 과 `src/japanese/farewells/mod.rs`를 찾으라고 말하는 것이다. 이들이 서브 모듈들을 갖지 않기 때문에 우리는 이들을 `src/english/greetings.rs`와 `src/janapnese/farewells.rs`로 정했다. 휴!
Again, these declarations tell Rust to look for either
`src/english/greetings.rs` and `src/japanese/greetings.rs` or
`src/english/farewells/mod.rs` and `src/japanese/farewells/mod.rs`. Because
these sub-modules don’t have their own sub-modules, we’ve chosen to make them
`src/english/greetings.rs` and `src/japanese/farewells.rs`. Whew!

`src/english/greetings.rs`와 `src/japanese/farewells.rs`은 지금은 비어있다. 함수 몇개를 추가해보자.
The contents of `src/english/greetings.rs` and `src/japanese/farewells.rs` are
both empty at the moment. Let’s add some functions.

다음을 `src/english/greetings.rs`에 넣어라:
Put this in `src/english/greetings.rs`:

```rust
fn hello() -> String {
"Hello!".to_string()
}
```

다음을 `src/english/farewells.rs`에 넣어라:
Put this in `src/english/farewells.rs`:

```rust
fn goodbye() -> String {
"Goodbye.".to_string()
}
```

다음을 `src/japanese/greetings.rs`에:
Put this in `src/japanese/greetings.rs`:

```rust
fn hello() -> String {
"こんにちは".to_string()
}
```

당연한 얘기지만, 이 내용들을 웹에서 복사해 넣어도 되고, 아니면 그냥 치던가 알아서 해라. 당신이 '곤니찌와'를 쳐넣는 것은 모듈 시스템에 별로 중요한 내용은 아니니까.
Of course, you can copy and paste this from this web page, or just type
something else. It’s not important that you actually put ‘konnichiwa’ to learn
about the module system.

다음을 `src/japanese/farewells.rs` 에:
Put this in `src/japanese/farewells.rs`:

```rust
fn goodbye() -> String {
"さようなら".to_string()
}
```

(이건 '사요나라'지, 궁금할까봐.)
(This is ‘Sayōnara’, if you’re curious.)

이제 우리는 우리의 crate에 몇개의 함수들을 넣어놨고, 이를 다른 crate에서 호출해보자.
Now that we have some functionality in our crate, let’s try to use it from
another crate.

# Importing External Crates
외부 Crates들 import하기.

우리는 라이브러리 crate를 가졌다. 이를 import해서 실행할 수 있는 crate를 만들어보자.

We have a library crate. Let’s make an executable crate that imports and uses
our library.

`src/main.rs`를 만들고 다음을 넣어보자(아직 컴파일 안됨):
Make a `src/main.rs` and put this in it (it won’t quite compile yet):

```rust,ignore
extern crate phrases;

fn main() {
println!("Hello in English: {}", phrases::english::greetings::hello());
println!("Goodbye in English: {}", phrases::english::farewells::goodbye());

println!("Hello in Japanese: {}", phrases::japanese::greetings::hello());
println!("Goodbye in Japanese: {}", phrases::japanese::farewells::goodbye());
}
```

`extern crate`는 러스트에게 우리가 `phrases` crate가 컴파일하고 링크할 때 필요하다고 말하는 것이다. 이후 우리는 `phrases` 모듈들을 사용할 수 있다. 우리가 전에 언급했듯, 더블콜론을 서브모듈과 그들의 내부 함수를 참조하기 위해 사용할 수 있다.
The `extern crate` declaration tells Rust that we need to compile and link to
the `phrases` crate. We can then use `phrases`’ modules in this one. As we
mentioned earlier, you can use double colons to refer to sub-modules and the
functions inside of them.

(주의: crate를 import할 때 "like-this"처럼 대쉬가 포함되어 있을 경우, 러스트 식별자는 이를 검증하지 않기에, 밑줄로 바꿔서 `extern crate like_this;`처럼 사용하도록 하자.)
(Note: when importing a crate that has dashes in its name "like-this", which is not a valid Rust identifier, it will be converted by changing the dashes to underscores, so you would write `extern crate like_this;`.)

또한, Cargo는 `src/main.rs`를 라이브러리 crate보다 binary crate를 root로 가정한다. 이제, 우리의 패키지는 `src/lib.rs`와 `src/main.rs`로 두 crate들 갖는다. 이 패턴은 실행 형태의 crate에게 매우 흔한 구조이다: 대다수의 기능들을 라이브러리 crate에 넣고 실행 가능한 crate는 라이브러리를 사용하는 형태를 취한다. 이 방식으로 다른 프로그램도 라이브러리 crate를 사용할 수 있으므로, 생각해만한 좋은 구분 방법이다.
Also, Cargo assumes that `src/main.rs` is the crate root of a binary crate,
rather than a library crate. Our package now has two crates: `src/lib.rs` and
`src/main.rs`. This pattern is quite common for executable crates: most
functionality is in a library crate, and the executable crate uses that
library. This way, other programs can also use the library crate, and it’s also
a nice separation of concerns.

이는 아직 동작하지 않긴 한다. 우리는 다음과 유사한 네 개의 에러를 얻는다:
This doesn’t quite work yet, though. We get four errors that look similar to
this:

```bash
$ cargo build
Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
src/main.rs:4:38: 4:72 error: function `hello` is private
src/main.rs:4 println!("Hello in English: {}", phrases::english::greetings::hello());
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: in expansion of format_args!
:2:25: 2:58 note: expansion site
:1:1: 2:62 note: in expansion of print!
:3:1: 3:54 note: expansion site
:1:1: 3:58 note: in expansion of println!
phrases/src/main.rs:4:5: 4:76 note: expansion site
```

기본적으로, 러스트에서는 모든 것이 private이다. 이를 좀더 심도 있게 얘기해보자.
By default, everything is private in Rust. Let’s talk about this in some more
depth.

# Exporting a Public Interface
공개된 Interface Export하기

러스트는 당신에게 당신의 interface가 public할 때만 정확하게 컨트롤 권한을 제공하는데, 그래서 private가 기본 값이다. 이들을 public하게 만들기 위해, 당신은 `pub`이라는 키워드를 사용해야 한다. `english`모듈을 첫 번째로 집중해서, `src/main.rs`를 다음과 같이 줄여보자:

Rust allows you to precisely control which aspects of your interface are
public, and so private is the default. To make things public, you use the `pub`
keyword. Let’s focus on the `english` module first, so let’s reduce our `src/main.rs`
to just this:

```rust,ignore
extern crate phrases;

fn main() {
println!("Hello in English: {}", phrases::english::greetings::hello());
println!("Goodbye in English: {}", phrases::english::farewells::goodbye());
}
```

우리의 `src/lib.rs`에서, `pub`을 `english` 모둘 선언부에 추가하자:
In our `src/lib.rs`, let’s add `pub` to the `english` module declaration:

```rust,ignore
pub mod english;
mod japanese;
```

우리의 `src/english/mod.rs`에서는 둘다 `pub`으로 만들자:
And in our `src/english/mod.rs`, let’s make both `pub`:

```rust,ignore
pub mod greetings;
pub mod farewells;
```

우리의 `src/english/greetings.rs`에서는, `pub`을 우리의 `fn` 선언부에 추가하자:
In our `src/english/greetings.rs`, let’s add `pub` to our `fn` declaration:

```rust,ignore
pub fn hello() -> String {
"Hello!".to_string()
}
```

그리고 `src/english/farewells.rs`에도:
And also in `src/english/farewells.rs`:

```rust,ignore
pub fn goodbye() -> String {
"Goodbye.".to_string()
}
```

이제, 우리 crate를 컴파일하자, 비록 `japanese`함수를 하용하지 않는 것에 경고를 보이더라도:
Now, our crate compiles, albeit with warnings about not using the `japanese`
functions:

```bash
$ cargo run
Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
src/japanese/greetings.rs:1:1: 3:2 warning: function is never used: `hello`, #[warn(dead_code)] on by default
src/japanese/greetings.rs:1 fn hello() -> String {
src/japanese/greetings.rs:2 "こんにちは".to_string()
src/japanese/greetings.rs:3 }
src/japanese/farewells.rs:1:1: 3:2 warning: function is never used: `goodbye`, #[warn(dead_code)] on by default
src/japanese/farewells.rs:1 fn goodbye() -> String {
src/japanese/farewells.rs:2 "さようなら".to_string()
src/japanese/farewells.rs:3 }
Running `target/debug/phrases`
Hello in English: Hello!
Goodbye in English: Goodbye.
```

`pub`는 또한 `struct`와 그들의 멤버 필드에 접근할 수 있게 해준다. 러스트가 안전에 중점을 두고 있는 만큼, `struct`를 만드는 것은 그들의 멤버들을 public하게 하지 않는다: 당신은 반드시 `pub`를 통해 필드에 명시해야 한다.
`pub` also applies to `struct`s and their member fields. In keeping with Rust’s
tendency toward safety, simply making a `struct` public won't automatically
make its members public: you must mark the fields individually with `pub`.

이제 우리의 함수가 public하기에, 우리는 이들을 사용할 수 있다. 대단하다! 하지만 `phrases::english::greetings::hello()`와 같이 사용하는 것은 너무 길고 반복적인 작업이다. 러스트는 이를 현재 범위에서 다른 이름으로 import할 수 있게 해주니까, 짧은 다른 이름으로 사용하도록 해라. `use`라는 키워드에 대해 알아보자.
Now that our functions are public, we can use them. Great! However, typing out
`phrases::english::greetings::hello()` is very long and repetitive. Rust has
another keyword for importing names into the current scope, so that you can
refer to them with shorter names. Let’s talk about `use`.

# Importing Modules with `use`
`use`와 함께 모듈 import하기

러스트는 `use`키워를 제공하는데 이는 import 이름을 현재 범위에서 사용할 수 있게 해준다. `src/main.rs`를 다음과 같이 바꿔보자:

Rust has a `use` keyword, which allows us to import names into our local scope.
Let’s change our `src/main.rs` to look like this:

```rust,ignore
extern crate phrases;

use phrases::english::greetings;
use phrases::english::farewells;

fn main() {
println!("Hello in English: {}", greetings::hello());
println!("Goodbye in English: {}", farewells::goodbye());
}
```

두 `use` 줄은 각 모듈을 현재 범위로 import 하기에, 훨씬 짧은 이름으로 그들의 함수를 참조할 수 있게 된다. 규칙(Convention)에 따라, 함수를 import할 때, 함수를 직접 사용하는 것 보다는 그의 모듈과 함께 사용하도록 해라. 다르게 얘기하면, 당신은 다음과 같이 사용할 수 있다:
The two `use` lines import each module into the local scope, so we can refer to
the functions by a much shorter name. By convention, when importing functions, it’s
considered best practice to import the module, rather than the function directly. In
other words, you _can_ do this:

```rust,ignore
extern crate phrases;

use phrases::english::greetings::hello;
use phrases::english::farewells::goodbye;

fn main() {
println!("Hello in English: {}", hello());
println!("Goodbye in English: {}", goodbye());
}
```

하지만 이렇게 사용하는 것은 자연스럽지 않다. 이런 방식은 이름의 충돌을 야기하기 쉽다. 지금처럼 짧은 프로그램에서는, 큰 문제가 아니지만, 커지기 시작하면, 그건 큰 문제가 된다. 이름이 충돌하면 러스트는 컴파일 에러를 낸다. 예를들어 우리가 `japanese` 함수를 public으로 만들고 다음처럼 사용하고자 하면:
But it is not idiomatic. This is significantly more likely to introduce a
naming conflict. In our short program, it’s not a big deal, but as it grows, it
becomes a problem. If we have conflicting names, Rust will give a compilation
error. For example, if we made the `japanese` functions public, and tried to do
this:

```rust,ignore
extern crate phrases;

use phrases::english::greetings::hello;
use phrases::japanese::greetings::hello;

fn main() {
println!("Hello in English: {}", hello());
println!("Hello in Japanese: {}", hello());
}
```

러스트는 컴파일 과정에서 에러를 낸다:
Rust will give us a compile-time error:

```text
Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
src/main.rs:4:5: 4:40 error: a value named `hello` has already been imported in this module [E0252]
src/main.rs:4 use phrases::japanese::greetings::hello;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `phrases`.
```

우리가 같은 모듈에서 다수의 이름을 import한다면, 우리는 이를 두번 쳐댈 필요가 없다. 이런 식으로 사용하기 보다:
If we’re importing multiple names from the same module, we don’t have to type it out
twice. Instead of this:

```rust,ignore
use phrases::english::greetings;
use phrases::english::farewells;
```

이렇게 짧게 사용할 수 있다:
We can use this shortcut:

```rust,ignore
use phrases::english::{greetings, farewells};
```

## Re-exporting with `pub use`
`pub use`로 재-export하기

`use`는 단지 짧은 식별자를 위해 사용하는 것은 아니다. 당신은 당신의 crate에서 다른 모듈에 있는 함수의 재-export를 사용할 수 있다. 이는 당신의 코드에 구조적으로 직접적으로 map되지는 않지만 외부 인터페이스를 전달할 수 있도록 허용한다.

You don’t just use `use` to shorten identifiers. You can also use it inside of your crate
to re-export a function inside another module. This allows you to present an external
interface that may not directly map to your internal code organization.

예제를 한번 보자. `src/main.rs`를 다음과 같이 수정해라:
Let’s look at an example. Modify your `src/main.rs` to read like this:

```rust,ignore
extern crate phrases;

use phrases::english::{greetings,farewells};
use phrases::japanese;

fn main() {
println!("Hello in English: {}", greetings::hello());
println!("Goodbye in English: {}", farewells::goodbye());

println!("Hello in Japanese: {}", japanese::hello());
println!("Goodbye in Japanese: {}", japanese::goodbye());
}
```

그리고, `src/lib.rs`를 수정해 `japanese`를 mod public 으로 만들어라:
Then, modify your `src/lib.rs` to make the `japanese` mod public:

```rust,ignore
pub mod english;
pub mod japanese;
```

다음으로, `src/japanese/greetings.rs`에 두 함수를 public으로 만들어라:
Next, make the two functions public, first in `src/japanese/greetings.rs`:

```rust,ignore
pub fn hello() -> String {
"こんにちは".to_string()
}
```

그 다음으로 `src/japanese/farewells.rs`:
And then in `src/japanese/farewells.rs`:

```rust,ignore
pub fn goodbye() -> String {
"さようなら".to_string()
}
```

마지막으로, 당신의 `src/japanese/mod.rs`를 다음과 같이 수정:
Finally, modify your `src/japanese/mod.rs` to read like this:

```rust,ignore
pub use self::greetings::hello;
pub use self::farewells::goodbye;

mod greetings;
mod farewells;
```

`pub use`는 우리의 모듈 계층의 함수를 우리의 범위로 끌어오도록 하는 선언이다. 우리가 `japanese`모듈의 `pub use`로 선언하여, `phrases::japanese::greetings::hello()` `phrases::japanese::farewells::goodbye()`에 함수가 존재하더라도 우리는 `phrases::japanese::hello()`와 `phrases::japanese::goodbye()`처럼 사용할 수 있다. 우리 내부의 구성은 외부 인터페이스를 정의하지 않았다.
The `pub use` declaration brings the function into scope at this part of our
module hierarchy. Because we’ve `pub use`d this inside of our `japanese`
module, we now have a `phrases::japanese::hello()` function and a
`phrases::japanese::goodbye()` function, even though the code for them lives in
`phrases::japanese::greetings::hello()` and
`phrases::japanese::farewells::goodbye()`. Our internal organization doesn’t
define our external interface.

여기서 우리는 `pub use`를 사용하여 각 함수를 `japanese` 범위로 끌어들였다. 여기서 우리는 와일드카드 문법을 사용하여 `greetings`에 있는 모든 것을 현재 범위로 끌어들일 수 있다: `pub use self::greetings::*`.
Here we have a `pub use` for each function we want to bring into the
`japanese` scope. We could alternatively use the wildcard syntax to include
everything from `greetings` into the current scope: `pub use self::greetings::*`.

`self`는 뭘까? 음, 그건 기본적으로 `use` 선언이 절대 경로 선언이기 때문에, 당신의 crate root를 시작지점으로 생각한다. `self`는 구조적인 위치 대신(주:crate가 존재하는 절대경로) 상대 경로(주:self인 자신의 위치에서 시작되는 경로)를 참조할 수 있도록 만들어준다. 여기에 `use`를 사용하는 특별한 형식이 있다: 당신은 `use super::`를 현재에서 한 단계 상위 계층에 도달하록 한다. 어떤 사람들은 `self`를 `.`로 `suepr`를 `..`로 생각하곤 한다, 많은 쉘에서 이는 현재 경로와 상위 경로의 표현이다.
What about the `self`? Well, by default, `use` declarations are absolute paths,
starting from your crate root. `self` makes that path relative to your current
place in the hierarchy instead. There’s one more special form of `use`: you can
`use super::` to reach one level up the tree from your current location. Some
people like to think of `self` as `.` and `super` as `..`, from many shells’
display for the current directory and the parent directory.

`use`의 외부에서, 경로는 상대적이다: `foo::bar()`는 우리가 있는 곳에서 상대적인 `foo`의 내부 함수를 참조한다. 만약 `::` 접두어가 붙어 `::foo::bar()`같이 사용되면, 이는 `foo`와 다른 참조이고, 당신의 create root 로 부터 절대 경로에 존재하는 `foo`를 참조한다.
Outside of `use`, paths are relative: `foo::bar()` refers to a function inside
of `foo` relative to where we are. If that’s prefixed with `::`, as in
`::foo::bar()`, it refers to a different `foo`, an absolute path from your
crate root.

이는 빌드되고 실행 된다:
This will build and run:

```bash
$ cargo run
Compiling phrases v0.0.1 (file:///home/you/projects/phrases)
Running `target/debug/phrases`
Hello in English: Hello!
Goodbye in English: Goodbye.
Hello in Japanese: こんにちは
Goodbye in Japanese: さようなら
```

## Complex imports
복잡한 import

러스트가 제공하는 여러 고급 옵션으로 편리하고 밀도있게 `extern crate`와 `use` 문을 사용할 수 있다. 예제:

Rust offers several advanced options that can add compactness and
convenience to your `extern crate` and `use` statements. Here is an example:

```rust,ignore
extern crate phrases as sayings;

use sayings::japanese::greetings as ja_greetings;
use sayings::japanese::farewells::*;
use sayings::english::{self, greetings as en_greetings, farewells as en_farewells};

fn main() {
println!("Hello in English; {}", en_greetings::hello());
println!("And in Japanese: {}", ja_greetings::hello());
println!("Goodbye in English: {}", english::farewells::goodbye());
println!("Again: {}", en_farewells::goodbye());
println!("And in Japanese: {}", goodbye());
}
```

무엇이 중한겨?
What's going on here?

[#본문에 오타가 있음 farewell -> greeting 으로 변경]
첫 째로, `extern crate`와 `use`는 모두 import시에 이름을 명명할 수 있도록 한다. 그래서 create가 아직 "phrases"로 명명됐어도, 우리는 이를 "sayings"로 참조할 수 있다. 비슷하게 첫 `use`문장은 `japanese::greeting`모듈을 crate에서 땡겨오지만, `greeting`로 간단히 쓰기보다 `jp_farewells`로 사용할 수 있게 한다.
First, both `extern crate` and `use` allow renaming the thing that is being
imported. So the crate is still called "phrases", but here we will refer
to it as "sayings". Similarly, the first `use` statement pulls in the
`japanese::farewells` module from the crate, but makes it available as
`jp_farewells` as opposed to simply `farewells`. This can help to avoid
ambiguity when importing similarly-named items from different places.

두 번째 `use`문은 `sayings::japanese::farewells` 모듈에서 모든 심볼을 댕겨오기 위해서 별마크를 사용했다. 당신이 보다시피 이후에 우리는 `goodbye` 함수를 아무런 모듈 참조자 없이 호출할 수 있다. 이런 식의 사용은 자제하는게 좋다.
The second `use` statement uses a star glob to bring in _all_ symbols from the
`sayings::japanese::farewells`module. As you can see we can later refer to
the Japanese `goodbye` function with no module qualifiers. This kind of glob
should be used sparingly.

세 번째 `use`문은 부가 설명이 필요 없을 것 같다. 이는 "괄호 확장"을 사용하는데 세 개의 `use`문을 하나로 합친 것이다. (리눅스 쉘 스크립트를 사용해다면 비슷하게 느껴질거다) 이를 압축해제하면 다음과 같이 세 문장이 나온다:
The third `use` statement bears more explanation. It's using "brace expansion"
globbing to compress three `use` statements into one (this sort of syntax
may be familiar if you've written Linux shell scripts before). The
uncompressed form of this statement would be:
```rust,ignore
use sayings::english;
use sayings::english::greetings as en_greetings;
use sayings::english::farewells as en_farewells;
```
보다시피, 중괄호는 `use`문을 통해 동일 경로에 있는 다수의 아이템을 단축시키고, 여기서 `self`는 해당 경로에 대한 참조를 의미한다.
참고: 중골호는 중첩되거나 별마크와 함께 쓸 수 없다.

As you can see, the curly brackets compress `use` statements for several items
under the same path, and in this context `self` just refers back to that path.
Note: The curly brackets cannot be nested or mixed with star globbing.
documentation
# 4.4. 문서화 (Documentation) - 20%

문서화는 어떤 소프트웨어 프로젝트이든 중요한 부분이고, Rust에선 1등급입니다. 여러분의 프로젝트를 문서화하기위해 Rust가 제공하는 도구에 대해서 얘기해볼까요?

## `rustdoc`에 대해 (About `rustdoc`)

Rust 배포본은 `rustdoc`이라고 하는 문서를 생성해내는 도구를 포함하고 있습니다. 또한 `rustdoc`은 Cargo 명령인 `cargo doc`을 통해서 사용됩니다.

문서는 두 가지 방법으로 생성될 수 있습니다. 하나는 소스 코드로부터 생성하는 방법이고, 다른 하나는 별도의 마크다운 파일로부터 생성하는 방법입니다.

## 소스 코드 문서화 (Documenting source code)

Rust 프로젝트를 문서화하는 주된 방법은 소스 코드에 단 주석을 통해서 입니다. 이 목적을 위해 문서 주석을 사용할 수 있습니다.

```rust,ignore
/// Constructs a new `Rc`.
///
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// ```
pub fn new(value: T) -> Rc {
// implementation goes here
}
```

이 코드는 [다음과 같은][rc-new] 형태의 문서를 생성합니다. I've left the
implementation out, with a regular comment in its place.

여기에서 확인해야 할 첫 번재 내용은 `//` 대신에 `///`를 사용한다는 것입니다. 세 개의 슬래시는 문서 주석을 나타냅니다.

문서 주석은 마크다운으로 작성합니다.

Rust는 이런 주석들을 추적하고, 문서를 생성할 때 사용합니다. 열거형 같은 것을 문서화할 때 중요합니다.

```rust
/// The `Option` type. See [the module level documentation](../) for more.
enum Option {
/// No value
None,
/// Some value `T`
Some(T),
}
```

위 코드는 동작하지만, 다음 코드는 동작하지 않습니다.

```rust,ignore
/// The `Option` type. See [the module level documentation](../) for more.
enum Option {
None, /// No value
Some(T), /// Some value `T`
}
```

위 코드에서는 아래와 같은 오류가 날 것입니다.

```text
hello.rs:4:1: 4:2 error: expected ident, found `}`
hello.rs:4 }
^
```

이 [불행한 오류](https://github.com/rust-lang/rust/issues/22547)는 정상적인 동작입니다. 문서 처리를 수행하면 그 뒤에 따라오는 글들을 모두 주석으로 처리하며, 주석 뒤에는 아무것도 없는 것으로 인식합니다.

[rc-new]: http://doc.rust-lang.org/nightly/std/rc/struct.Rc.html#method.new

### 문서 주석 적기 (Writing documentation comments)

어쨌든, 주석의 각 부분을 자세히 다뤄보겠습니다.

```rust
/// Constructs a new `Rc`.
# fn foo() {}
```

문서 주석의 첫 줄은 대상의 기능을 짧게 요약하세요. 한문장으로. 기본만. 고수준으로.

```rust
///
/// Other details about constructing `Rc`s, maybe describing complicated
/// semantics, maybe additional options, all kinds of stuff.
///
# fn foo() {}
```

위 예제에는 요약된 설명만 기재되어 있지만, 더 언급할 것이 있다면 새 단락으로 설명을 추가할 수 있습니다.

#### 특별한 섹션 (Special sections)

다음은 특별한 섹션입니다. `#`은 헤더를 의미합니다. 주로 사용되는 헤더는 네 종류가 있습니다. 현재는 특별한 문법은 아니고, 단지 관습입니다.

```rust
/// # Panics
# fn foo() {}
```

Rust에서 회복할 수 없는 함수의 오용(예를 들어, 프로그래밍 오류)은 적어도 현재 스레드 전부를 죽이는 문제(흔히 panic으로 표현)를 야기합니다. 만약 여러분의 함수가 다음과 같이 사소하지 않은 기능을 가지고 있다면, 즉, panic이 감지/강요된다면, 문서화는 아주 중요합니다.

```rust
/// # Failures
# fn foo() {}
```

여러분의 함수나 메소드가 `Result`을 반환한다면, `Err(E)`를 반환해서 상태를 기술하는 것은 좋습니다. 실패는 타입 시스템으로 코드화되기 때문에, 이것은 `Panics`보다 약간 덜 중요합니다. 하지만 여전히 이렇게 하는 것은 좋습니다.

```rust
/// # Safety
# fn foo() {}
```

여러분의 함수가 `unsafe`라면, 어떤 불변의 호출자가 책임을 지고 있는지 설명해야 할 것입니다.

```rust
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// ```
# fn foo() {}
```

4변째 `Examples` 입니다. 함수나 method를 사용하기 위한 하나 이상의 예제를 추가하는 것이 사용자에게 큰 도움이 될 것입니다. 이 예제들은 곧 다시 언급할 코드 블록 주석에 포함될 것이며, 그 때 더 자세하게 설명될 것입니다.

```rust
/// # Examples
///
/// Simple `&str` patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
/// assert_eq!(v, vec!["Mary", "had", "a", "little", "lamb"]);
/// ```
///
/// More complex patterns with a lambda:
///
/// ```
/// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
/// assert_eq!(v, vec!["abc", "def", "ghi"]);
/// ```
# fn foo() {}
```

위 코드 블록 주석들에 대해 더 자세하게 알아보도록 하겠습니다.

#### 코드 블록 주석 (Code block annotations)

주석 내에 Rust 코드를 적고 싶다면, 세 개의 역따옴표를 사용하세요.

```rust
/// ```
/// println!("Hello, world");
/// ```
# fn foo() {}
```

Rust 코드가 아니라면, 언어 이름을 표기할 수 있습니다.

```rust
/// ```c
/// printf("Hello, world¶
");
/// ```
# fn foo() {}
```

표기한 언어에 따라 구문이 강조될 것입니다. 단순히 텍스트를 보여주려면, `text`를 적으세요.

`rustdoc`에서 이 항목을 인식하기 때문에, 정확한 언어를 선택하는 것은 중요합니다. 적합한 값을 적용했는지 확인하기 위해 실제로 당신의 예제를 테스트하는 데 사용되기도 합니다. 만약 당신이 C code를 사용하고 이 부분을 비워놓았다면 `rustdoc`은 예제를 Rust 코드로 인식하며, 문서화 작업 중 이에 대한 complain이 발생할 것입니다.

## 테스트로서의 문서화 (Documentation as tests)

샘플 예제 문서화로 논의해봅시다.

```rust
/// ```
/// println!("Hello, world");
/// ```
# fn foo() {}
```

여기서 `fn main()`이나 다른 건 필요없다는 것을 알게될 것입니다. `rustdoc`은 자동으로 당신의 코드를 감싸는 main() 래퍼를 알맞은 곳에 추가할 것입니다.

예제를 봅시다:

```rust
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// ```
# fn foo() {}
```

테스팅으로 완성됩니다:

```rust
fn main() {
use std::rc::Rc;
let five = Rc::new(5);
}
```

다음은 rustdoc이 후 처리를 하기 위해 사용하는 전체 알고리즘의 예입니다:

1. Any leading `#![foo]` attributes are left intact as crate attributes.
2. Some common `allow` attributes are inserted, including
`unused_variables`, `unused_assignments`, `unused_mut`,
`unused_attributes`, and `dead_code`. Small examples often trigger
these lints.
3. If the example does not contain `extern crate`, then `extern crate
;` is inserted.
2. Finally, if the example does not contain `fn main`, the remainder of the
text is wrapped in `fn main() { your_code }`

가끔 이걸로 충분하지 않을 때가 있습니다. 예를 들면, 우리가 지난번에 `///`로 시작하는 모든 코드 샘플에 관해 논의한 적이 있었나요? 로우 텍스트를 봅시다:

```text
/// Some documentation.
# fn foo() {}
```

출력과 달라 보입니다:

```rust
/// Some documentation.
# fn foo() {}
```

그렇습니다: 당신은 `#`으로 시작하는 줄을 추가할 수 있습니다. 그러면 해당 줄은 출력에서 보이지 않습니다. 이를 강점으로 활용할 수 있습니다. 이 예시에서 문서 주석은 몇 가지 함수를 필요로 합니다. 만일 제가 여러분에게 문서 주석을 보여주고 싶다면, 아래에 함수 정의부을 추가해야 합니다. 동시에, 이는 단지 컴파일러를 만족시키기 위한 것이므로, 이를 숨겨 예제를 더 분명하게 만들자. 더 긴 예제를 통해 이 기법을 설명하면서, 테스트 가능함을 당신의 문서에 유지해보자. 예로 살펴볼 코드:
At the same time, it's just there to satisfy the compiler, so hiding it makes the example more clear. You can use this technique to explain longer examples in detail, while still preserving the testability of your
documentation. For example, this code:

```rust
let x = 5;
let y = 6;
println!("{}", x + y);
```

설명을 추가해보자:
Here's an explanation, rendered:

처음에, 우리는 'x'에 5를 설정했다:
First, we set `x` to five:

```rust
let x = 5;
# let y = 6;
# println!("{}", x + y);
```

다음으로, 우리는 'y'에 6을 설정했다:
Next, we set `y` to six:

```rust
# let x = 5;
let y = 6;
# println!("{}", x + y);
```

마지막으로, 우리는 'x'와 'y'의 합을 출력한다:
Finally, we print the sum of `x` and `y`:

```rust
# let x = 5;
# let y = 6;
println!("{}", x + y);
```

동일한 설명의 순수 문자이다:
Here's the same explanation, in raw text:

> First, we set `x` to five:
>
> ```text
> let x = 5;
> # let y = 6;
> # println!("{}", x + y);
> ```
>
> Next, we set `y` to six:
>
> ```text
> # let x = 5;
> let y = 6;
> # println!("{}", x + y);
> ```
>
> Finally, we print the sum of `x` and `y`:
>
> ```text
> # let x = 5;
> # let y = 6;
> println!("{}", x + y);
> ```

당신이 설명하고자 하는 부분을 보여주기 위해서 예제의 부분을 반복하여 컴파일 되는지 확인해야 한다.
By repeating all parts of the example, you can ensure that your example still
compiles, while only showing the parts that are relevant to that part of your
explanation.

### Documenting macros
문서화 매크로

여기 문서화 매크로에 대한 설명이 있다:

Here’s an example of documenting a macro:

```rust
/// Panic with a given message unless an expression evaluates to true.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(1 + 1 == 2, “Math is broken.”);
/// # }
/// ```
///
/// ```should_panic
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(true == false, “I’m broken.”);
/// # }
/// ```
#[macro_export]
macro_rules! panic_unless {
($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
}
# fn main() {}
```

당신은 세 가지에 주목해야 한다: 우리는 우리의 `extern crate ` 줄을 추가해서, 우리는
You’ll note three things: we need to add our own `extern crate` line, so that
we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
`main()` as well. Finally, a judicious use of `#` to comment out those two
things, so they don’t show up in the output.

### Running documentation tests

To run the tests, either

```bash
$ rustdoc --test path/to/my/crate/root.rs
# or
$ cargo test
```

That's right, `cargo test` tests embedded documentation too. **However,
`cargo test` will not test binary crates, only library ones.** This is
due to the way `rustdoc` works: it links against the library to be tested,
but with a binary, there’s nothing to link to.

There are a few more annotations that are useful to help `rustdoc` do the right
thing when testing your code:

```rust
/// ```ignore
/// fn foo() {
/// ```
# fn foo() {}
```

The `ignore` directive tells Rust to ignore your code. This is almost never
what you want, as it's the most generic. Instead, consider annotating it
with `text` if it's not code, or using `#`s to get a working example that
only shows the part you care about.

```rust
/// ```should_panic
/// assert!(false);
/// ```
# fn foo() {}
```

`should_panic` tells `rustdoc` that the code should compile correctly, but
not actually pass as a test.

```rust
/// ```no_run
/// loop {
/// println!("Hello, world");
/// }
/// ```
# fn foo() {}
```

The `no_run` attribute will compile your code, but not run it. This is
important for examples such as "Here's how to start up a network service,"
which you would want to make sure compile, but might run in an infinite loop!

### Documenting modules

Rust has another kind of doc comment, `//!`. This comment doesn't document the next item, but the enclosing item. In other words:

```rust
mod foo {
//! This is documentation for the `foo` module.
//!
//! # Examples

// ...
}
```

This is where you'll see `//!` used most often: for module documentation. If
you have a module in `foo.rs`, you'll often open its code and see this:

```rust
//! A module for using `foo`s.
//!
//! The `foo` module contains a lot of useful functionality blah blah blah
```

### Documentation comment style

Check out [RFC 505][rfc505] for full conventions around the style and format of
documentation.

[rfc505]: https://github.com/rust-lang/rfcs/blob/master/text/0505-api-comment-conventions.md

## Other documentation

All of this behavior works in non-Rust source files too. Because comments
are written in Markdown, they're often `.md` files.

When you write documentation in Markdown files, you don't need to prefix
the documentation with comments. For example:

```rust
/// # Examples
///
/// ```
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
/// ```
# fn foo() {}
```

is just

~~~markdown
# Examples

```rust
use std::rc::Rc;

let five = Rc::new(5);
```
~~~

when it's in a Markdown file. There is one wrinkle though: Markdown files need
to have a title like this:

```markdown
% The title

This is the example documentation.
```

This `%` line needs to be the very first line of the file.

## `doc` attributes

At a deeper level, documentation comments are sugar for documentation attributes:

```rust
/// this
# fn foo() {}

#[doc="this"]
# fn bar() {}
```

are the same, as are these:

```rust
//! this

#![doc="/// this"]
```

You won't often see this attribute used for writing documentation, but it
can be useful when changing some options, or when writing a macro.

### Re-exports

`rustdoc` will show the documentation for a public re-export in both places:

```ignore
extern crate foo;

pub use foo::bar;
```

This will create documentation for bar both inside the documentation for the
crate `foo`, as well as the documentation for your crate. It will use the same
documentation in both places.

This behavior can be suppressed with `no_inline`:

```ignore
extern crate foo;

#[doc(no_inline)]
pub use foo::bar;
```

### Controlling HTML

You can control a few aspects of the HTML that `rustdoc` generates through the
`#![doc]` version of the attribute:

```rust
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
html_root_url = "https://doc.rust-lang.org/")]
```

This sets a few different options, with a logo, favicon, and a root URL.

## Generation options

`rustdoc` also contains a few other options on the command line, for further customization:

- `--html-in-header FILE`: includes the contents of FILE at the end of the
`...` section.
- `--html-before-content FILE`: includes the contents of FILE directly after
``, before the rendered content (including the search bar).
- `--html-after-content FILE`: includes the contents of FILE after all the rendered content.

## Security note

The Markdown in documentation comments is placed without processing into
the final webpage. Be careful with literal HTML:

```rust
///
# fn foo() {}
```
getting-started
# 2. 시작하기(Getting Started) - 2100%

이 책의 첫 번째 장을 통해 여러분은 Rust와 Rust에 관련된 도구들을 챙기게 될 거에요. 먼저 우리는 Rust를 설치할 것입니다. 그 다음은 전통적인 "안녕, 세상아_Hello, World_" 프로그램이죠. 마지막으로 Rust의 빌드 시스템이자 패키지 매니저인 Cargo에 대해서 이야기할 것입니다.

# Rust 설치하기

먼저 Rust를 사용하기 위해선 Rust를 설치해야 합니다. 우선 여러분이 이 장에서 소개된 명령어들을 실행하려면 인터넷에 연결되어 있어야 합니다.

이 책에서는 터미널에서 사용되는 몇 개의 명령어의 시작을 `$` 를 표시하여 강조할 것입니다.
하지만 `$` 는 해당 라인이 커맨드라는 사실을 나타낼 뿐이므로 실제로 입력하지 않아도 됩니다.
인터넷에 존재하는 많은 튜토리얼과 예제에서 `$` 는 보통 유저(일반적인 권한을 가진 유저)가 실행하는 커맨드들의 앞에 표시하고, `#`은 관리자(관리자 권한을 가진 유저)가 실행하는 명령어들 앞에 표시하는 관습이 있는데요, 이 책도 역시 그 관습을 따릅니다.


## 플랫폼 지원

'러스트' 는 수많은 플랫폼에서 컴파일되고 실행될 수 있습니다. 러스트가 지원하는 플랫폼들은 크게 세 가지로 나뉠 수 있습니다.


### 단계 1

1단계 플랫폼들은 쉽게 생각해서 '빌드가 가능하고 실행 가능한' 플랫폼입니다. 정확히는 아래의 요구사항을 만족하는 플랫폼입니다.

요구사항 -
- 테스트를 수행하기 위한 자동화가 되어 있음.
- `rustlang/rust` 저장소에 새로운 변경사항이 있을 때 테스트를 통과하는지 확인함.
- 플랫폼을 공식적으로 지원함.
- 해당 플랫폼에서 러스트를 빌드하고 사용하기위한 문서가 작성돼있음.


| 타겟 플랫폼 | std |rustc|cargo| 비고 |
|-------------------------------|-----|-----|-----|----------------------------|
| `x86_64-pc-windows-msvc` | ✓ | ✓ | ✓ | 64-bit MSVC (Windows 7+) |
| `i686-pc-windows-gnu` | ✓ | ✓ | ✓ | 32-bit MinGW (Windows 7+) |
| `x86_64-pc-windows-gnu` | ✓ | ✓ | ✓ | 64-bit MinGW (Windows 7+) |
| `i686-apple-darwin` | ✓ | ✓ | ✓ | 32-bit OSX (10.7+, Lion+) |
| `x86_64-apple-darwin` | ✓ | ✓ | ✓ | 64-bit OSX (10.7+, Lion+) |
| `i686-unknown-linux-gnu` | ✓ | ✓ | ✓ | 32-bit Linux (2.6.18+) |
| `x86_64-unknown-linux-gnu` | ✓ | ✓ | ✓ | 64-bit Linux (2.6.18+) |

### Tier 2

2단계 플랫폼들은 러스트 코드를 빌드할 수 있는 플랫폼입니다. 자동화된 테스트는 수행되지 않기 때문에 이 플랫폼에서 완벽한 작동은 보장할 순 없지만 꽤 잘 작동합니다. 이 플랫폼에 대한 패치는 언제나 환영합니다!

요구사항-
- 자동화된 테스트가 있지만 실행되지는 않을 수 있음.
- `rustlang/rust` 저장소의 master branch에 변경사항이 있을 때 **빌드**가 되는지 확인함. 어떤 플랫폼에서는 완벽히 작동하는 반면, 어떤 플랫폼에서는 빌드만 될 수 있음.
- 플랫폼을 공식적으로 지원함.


| 타겟 플랫폼 | std |rustc|cargo| 비고 |
|-------------------------------|-----|-----|-----|----------------------------|
| `i686-pc-windows-msvc` | ✓ | ✓ | ✓ | 32-bit MSVC (Windows 7+) |

### 3단계

3단계 플랫폼들은 러스트를 지원하나, 최신 버전의 빌드와 검증 작업이 이루어지지 않은 플랫폼들을 말합니다. 이러한 플랫폼들을 개별 커뮤니티들에 의해 유지되는 경우가 많기 때문에 퀄리티가 보장되지 않을 수 있습니다. 포함 패키지들과 인스톨러가 공식적으로 제공되지 않지만 커뮤니티에 의해 지원 될 수도 있습니다.

| 타겟 플랫폼 | std |rustc|cargo| 비고 |
|-------------------------------|-----|-----|-----|----------------------------|
| `x86_64-unknown-linux-musl` | ✓ | | | 64-bit Linux with MUSL |
| `arm-linux-androideabi` | ✓ | | | ARM Android |
| `i686-linux-android` | ✓ | | | 32-bit x86 Android |
| `aarch64-linux-android` | ✓ | | | ARM64 Android |
| `arm-unknown-linux-gnueabi` | ✓ | ✓ | | ARM Linux (2.6.18+) |
| `arm-unknown-linux-gnueabihf` | ✓ | ✓ | | ARM Linux (2.6.18+) |
| `aarch64-unknown-linux-gnu` | ✓ | | | ARM64 Linux (2.6.18+) |
| `mips-unknown-linux-gnu` | ✓ | | | MIPS Linux (2.6.18+) |
| `mipsel-unknown-linux-gnu` | ✓ | | | MIPS (LE) Linux (2.6.18+) |
| `powerpc-unknown-linux-gnu` | ✓ | | | PowerPC Linux (2.6.18+) |
| `i386-apple-ios` | ✓ | | | 32-bit x86 iOS |
| `x86_64-apple-ios` | ✓ | | | 64-bit x86 iOS |
| `armv7-apple-ios` | ✓ | | | ARM iOS |
| `armv7s-apple-ios` | ✓ | | | ARM iOS |
| `aarch64-apple-ios` | ✓ | | | ARM64 iOS |
| `i686-unknown-freebsd` | ✓ | ✓ | | 32-bit FreeBSD |
| `x86_64-unknown-freebsd` | ✓ | ✓ | | 64-bit FreeBSD |
| `x86_64-unknown-openbsd` | ✓ | ✓ | | 64-bit OpenBSD |
| `x86_64-unknown-netbsd` | ✓ | ✓ | | 64-bit NetBSD |
| `x86_64-unknown-bitrig` | ✓ | ✓ | | 64-bit Bitrig |
| `x86_64-unknown-dragonfly` | ✓ | ✓ | | 64-bit DragonFlyBSD |
| `x86_64-rumprun-netbsd` | ✓ | | | 64-bit NetBSD Rump Kernel |
| `i686-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |
| `x86_64-pc-windows-msvc` (XP) | ✓ | | | Windows XP support |

이 목록은 더 추가 될 수 있고, 여기 나열된 것들만 3단계 플랫폼이란 건 아닙니다!


## 리눅스와 맥에서의 러스트 설치

당신이 리눅스 또는 맥을 쓰고 있다면, 설치를 위해 할 것은 다음의 명령어를 터미널에 입력하는 것뿐입니다.

```bash
$ curl -sSf https://static.rust-lang.org/rustup.sh | sh
```

이것은 설치 스크립트를 다운로드하여 설치를 진행하게 해줄 것입니다. 그리고 이 작업이 모두 잘 진행된다면 다음의 메시지가 나타날 것입니다.

```text
Welcome to Rust.

This script will download the Rust compiler and its package manager, Cargo, and
install them to /usr/local. You may install elsewhere by running this script
with the --prefix= option.

The installer will run under ‘sudo’ and may ask you for your password. If you do
not want the script to run ‘sudo’ then pass it the --disable-sudo flag.

You may uninstall later by running /usr/local/lib/rustlib/uninstall.sh,
or by running this script again with the --uninstall flag.

Continue? (y/N)
```

여기서 `y` (예)를 입력하고 편안히 설치를 기다리시면 됩니다.

## 윈도우에서의 러스트 설치

당신이 윈도우를 사용하고 있다면, 윈도우용 인스톨러를 받아서 사용해주세요 [installer][install-page].

[install-page]: https://www.rust-lang.org/install.html

## 러스트 제거

러스트를 제거하는 방법은 굉장히 쉽습니다. 리눅스와 맥에서 단지 언인스톨러 스크립트를 실행하기만 하면 됩니다.

```bash
$ sudo /usr/local/lib/rustlib/uninstall.sh
```

만약 당신이 윈도우의 편리한 인스톨러의 노예라면, 다시 `.msi`확장자를 가진 러스트 인스톨러를 다시 실행하여 제거 버튼을 누르면 됩니다.

## 문제 해결

러스트를 인스톨한 후 터미널을 열어 다음 명령어를 실행해 보십시오.

```bash
$ rustc --version
```

러스트의 버전과, 커밋 해쉬, 커밋 날짜가 보여야 러스트가 성공적으로 인스톨 된 것입니다!

만약 당신이 윈도우즈를 사용하고 위 작업에 실패하셨다면, 시스템 %PATH% 변수 안에 러스트 설치 경로가 들어있는지 확인하세요: `$ echo %PATH%`. 설치경로가 포함돼있지 않으면, 러스트를 설치한 폴더의 경로를 추가해주시길 바랍니다. _(어떻게 하는진 다들 아실 거라 믿습니다)_

불행하게도 윈도우 이외의 플랫폼에서 설치가 실패했다면
인스톨러를 다시 실행하여, "Change, repair, or remove installation" 페이지에서 "Change"를 선택하고 "Add to PATH"가 로컬 하드 드라이브에 설치되었는지 확인하세요. 직접 경로를 추가해야 할 경우에는, 러스트의 실행파일들을 "C:\Program Files\Rust stabel GNU 1.x\bin"와 같은 디렉토리에서 발견하실 수 있을 겁니다.

러스트는 자체적으로 링킹(linking)을 하지 않아서 사용자가 링커를 설치해야합니다. 설치는 특정 시스템에 의존성이 있는 만큼 더 자세한 내용은 해당 시스템의 문서를 참고하시기 바랍니다.

설치가 되지않았을 경우
, 도움을 받을 수 있는 곳이 여럿있습니다. 가장 쉬운곳은 공식[irc.mozilla.org의 #rust-beginners IRC 채널][beginner]이고 일반적인 토론은 [irc.mozilla.org의 #rust IRC 체널][irc] 입니다. IRC 클라이언트는 [Mibbit][mibbit] 을 사용하실 수 있습니다. IRC를 통해 다른 러스테이시언(Rustaceans) (러스트 사용자를 부르는 다소 웃기는 별명)들과 대화를 통해 도움을 받을 수 있습니다. 다른 곳으론, [사용자 포럼][users]과 [(우리들의 친구) Stack Overflow][stackoverflow]가 있습니다.

[beginner]: irc://irc.mozilla.org/#rust-beginners

[irc]: irc://irc.mozilla.org/#rust
[mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
[users]: https://users.rust-lang.org/
[stackoverflow]: http://stackoverflow.com/questions/tagged/rust

러스트 인스톨러는 자동적으로 공식 문서를 로컬에 저장해줍니다. 유닉스 기반 운영체제라면 `/usr/local/share/doc/rust`에, 윈도우 기반이라면 `(러스트 인스톨 경로)/share/doc`에서 찾을 수 있습니다.

# Hello, world!

이제 러스트를 설치했으니, 간단한 첫 프로그램을 만들어 봅시다. 암묵적인 세계적 프로그래머 전통을 따라서 우리는 작고 아름다운 _(모두가 아는.)_ 'Hello, world!' 프로그램을 만들어 볼 것입니다.

이러한 작은 프로그램을 만들어보는 건 컴파일러가 잘 작동하는지 확인할 수 있습니다. 그리고 화면에 문자를 출력하는 건 가장 일반적인 것들임으로 빨리해볼수록 좋죠.

> 참고: 이 문서는 기본적으로 터미널에서 작업하는 것을 전제로 쓰여있습니다. 러스트는 러스트자체의 코딩 툴이 없습니다. 하지만 러스트를 지원하는 [SolidOak][soak]라는 IDE가 존재합니다. 그리고 커뮤니티에는 사용자들이 개발한 수많은 확장기능들이 있고, 러스트 재단에서 [수많은 에디터][various editors]들을 위한 러스트 플러그인을 제공합니다. 당신이 사용하는 IDE나 에디터들의 설정은 이제부터 진행할 튜토리얼과는 조금 다른 모양과 설정을 가지고 있을 수 있습니다. 그러니 IDE나 추가 에디터를 사용할 경우 적절히 설정을 변경해서 사용해주십시오.

[soak]: https://github.com/oakes/SolidOak
[various editors]: https://github.com/rust-lang/rust/blob/master/src/etc/CONFIGS.md

## 프로젝트 파일 생성

첫째로, 러스트 코드를 만들어 봅시다. 러스트는 당신이 어디서 코드를 만들든 볶든 우리든 상관하지 않지만, 우리들은 새로운 프로젝트 폴더를 당신의 홈디렉터리에 생성할 것을 권장합니다. 다음의 명령어들은 간단히 프로젝트 폴더를 생성하는 법을 소개합니다.

```bash
$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world
```

> 참고: 당신이 윈도우에서 파워셀이 아닌 명령프롬포트를 사용하고 있다면, `~`문자는 작동하지 않을 것입니다.

## 러스트 프로그램을 작성하고 실행하기

다음으로, 새로운 소스 파일을 만들고 *main.rs*로 이름을 작성해주십시오. 러스트 소스 파일은 항상 *.rs*를 확장자로 가집니다. 만약 당신의 파일 이름에 한 단어 이상 사용했다면, 스페이스 대신 밑줄문자 *_* 를 사용해주십시오. 예로, *wonderful rust language.rs* 를 *wonderful_rust_language.rs* 로 작성해주십시오.

이제 *main.rs*파일을 열어서 다음의 코드를 입력해봅시다.

```rust
fn main() {
println!("Hello, world!");
}
```

파일을 빌드하기 위해서는 터미널로 일단 돌아갑니다. 당신이 리눅스와 맥을 사용하고 있다면 다음 명령어들을 실행해주세요.

```bash
$ rustc main.rs
$ ./main
Hello, world!
```

당신의 운영체제가 윈도우라면, 위 명령어 중에서 그저 `main` 을 `main.exe`로 바꾸면 됩니다. 그리고 빌드 후에는 당신의 운영체제와 상관없이 터미널에 `Hello, world!` 가 출력될 것입니다. 이것이 성공했다면, 이 텍스트는 당신이 첫 러스트로 출력한 텍스트가 된 것입니다! 러스트의 세계로 오신 당신을 정말 환영합니다!

## 간단한 러스트 문법러스트 프로그램의 해부

지금부터, 방금 작성한 "Hello, world" 프로그램에 대해 자세하게 설명하도록 하겠습니다. 그럼 첫 줄부터 보시죠.

```rust
fn main() {

}
```

이 코드 라인들은 러스트에서의 *함수*를 정의하고 있습니다. 이 `main`함수는 특별합니다: 이 함수는 모든 러스트 프로그램의 시작점입니다. 코드의 첫 줄은 "난 이름이 `main`이고 아무 매개변수도 필요로 하지 않으며 아무것도 리턴하지 않는 함수를 정의하고 있어요" 라고 말하고 있습니다. 만약 매개변수가 있다면 소괄호 기호`(` 와 `)` 사이로 들어가면 됩니다. 그리고 우리는 이 함수에서 아무것도 리턴을 하지 않을 것이니까, 우리는 리턴타입을 통째로 생략할 수 있습니다.

또한 함수 본문은 중괄호 `{` 와 `}`로 쌓여있습니다. 러스트는 모든 함수의 몸체를 중괄호로 둘러싸는 것을 요구합니다. 함수 선언과 같은 줄에 한 칸의 스페이스를 두고 중괄호를 여는 것이 좋은 코드 스타일이라 여겨집니다.

`main()` 함수 안에서:

```rust
println!("Hello, world!");
```

이 줄에서 이 작은 프로그램이 하는 모든 일이 실행됩니다: 화면에 텍스트를 띄우는 일이요. 이 한 줄에는 주목할 점이 꽤 많습니다. 그 중 첫번째는, 들여쓰기가 탭이 아니라 스페이스 네 개로 되어 있다는 점입니다.

두번째 주목해야 할 것은 `println!()` 부분입니다. 이것은 러스트의 *[매크로]*라고 부르는데 이걸로 러스트에서 메타프로그래밍을 합니다. 만약 이것 대신 함수를 호출하려 했다면`println()`(!가 없습니다)라고 썼겠죠. 러스트의 매크로에 관해서는 나중에 좀더 자세히 다루겠지만, `!`가 붙으면 그건 그냥 함수가 아니라 매크로라는 점은 알아두세요.

[매크로]: macros.html

다음은 *string*인 `"Hello, world!"` 부분입니다. string은 시스템 프로그래밍 언어에서 무척이나 복잡한 부분인데, 이것은 *[정적으로 할당된]* string입니다. 이 string을 `println!`에 인자로 전달하면 `println!()`이 받은 string을 화면에 띄워줍니다. 쉽죠?

[정적으로 할당된]: the-stack-and-the-heap.html

다음 줄은 세미콜론(`;`)으로 끝납니다. 러스트는 대부분의 것들이 문(statement)보다 식(expression)인 *[표현식 지향]*적인 언어입니다. `;`는 표현식이 끝났고 다음 표현식이 시작할 준비가 되었다는 것을 가리킵니다. 러스트 코드의 대부분의 줄은 `;`로 끝납니다.

[표현식 지향]: glossary.html#expression-oriented-language

## 컴파일과 실행은 다른 단계로 이루어짐

"러스트 프로그램을 작성하고 실행하기"에서 갓 만든 프로그램을 실행해보았습니다. 이제 각각의 단계들을 하나씩 파헤쳐봅시다.

러스트 프로그램을 실행하기 전에 먼저 컴파일을 해야 합니다. 명령어 `rustc` 뒤에 소스파일의 이름을 입력하면 러스트 컴파일러를 사용할 수 있습니다. 이렇게요.

```bash
$ rustc main.rs
```

C나 C++을 배웠다면 `gcc`나 `clang`이랑 비슷하게 느껴질 것입니다. 성공적으로 컴파일을 했으면 러스트는 바이너리 실행파일을 결과물로 내놓을 것입니다. Linux나 OSX의 셸에서 `ls` 명령으로 보면 이렇게 보입니다.

```bash
$ ls
main main.rs
```

윈도우에서는 이렇게 보입니다.

```bash
$ dir
main.exe main.rs
```

두 파일이 있는데, 하나는 `.rs` 확장자를 갖는 소스코드이고, 다른 하나가 실행파일입니다(윈도우에서는 `main.exe`, 다른 데서는 `main`). 이제 `main`이나 `main.exe` 파일을 실행하기만 하면 됩니다. 이렇게요.

```bash
$ ./main # or main.exe on Windows
```

*main.rs*가 "Hello, world!" 프로그램이면 터미널에 `Hello, world`를 띄울 겁니다.

루비나 파이썬, 자바스크립트같은 동적 언어를 배웠다면 컴파일과 실행과정이 분리되어 있는 것에 익숙치 않을 지도 모릅니다. 러스트는 *AOT 컴파일* 언어입니다. 그렇기 때문에 프로그램을 컴파일해서 누군가에게 주면 그 사람은 러스트가 깔려있지 않아도 그 프로그램을 실행할 수 있습니다. 만약에 `.rb`, `.py`, `.js` 파일을 준다면 각각 루비, 파이썬, 자바스크립트가 깔려있어야 실행할 수 있겠죠. 대신 컴파일하고 실행을 동시에 한 명령어로 수행할 수 있습니다. 프로그래밍 언어 디자인에서 모든 것은 등가교환입니다.

간단한 프로그램일때는 `rustc`로 그냥 컴파일하는 것이 편하지만 프로젝트가 커지면 프로젝트의 옵션들을 관리하고 소스를 관리하는 것을 좀더 쉽게 하고싶어질 것입니다. 이제, 진짜 러스트 프로그램을 쓰는 것을 도와줄 Cargo를 소개합니다.

# Hello, Cargo!

카고는 러스트의 빌드 시스템이자 패키지 매니저입니다. 러스트인들은 그들의 러스트 프로젝트를 관리하는데 카고를 사용합니다. 카고는 다음 세가지를 관리해줍니다. 코드를 빌드하고, 의존성이 있는 라이브러리를 다운로드하고, 그 라이브러리를 빌드합니다. 코드가 호출하고 있는 라이브러리를 '의존성'이라고 합니다. 코드가 거기에 의존하고 있으니까요.

가장 간단한 러스트 프로그램은 의존성이 없기 때문에 바로 함수를 작성하면 됩니다. 좀더 정교한 러스트 프로그램을 짜기 시작하면 의존성을 더하게 될텐데 이때 카고를 사용하면 훨씬 쉬워집니다.

거의 대부분의 러스트 프로젝트는 카고를 사용하고, 아마 이 책의 나머지 부분에서도 쭉 사용할 것입니다. 러스트 공식 인스톨러를 사용했다면 러스트와 함께 카고도 깔렸을 것입니다. 러스트를 다른 방법으로 설치했다면 이렇게 터미널에 쳐서 카고가 깔려있는지 체크해야 합니다.

```bash
$ cargo --version
```

버전이 보이면, 좋습니다! '`command not found`' 따위의 에러가 보이면, 러스트가 설치된 시스템의 매뉴얼을 보고 카고가 빠져있는지 확인해야 합니다.

## Cargo로 변환하기

이제 Hello World 프로그램을 Cargo로 변환 해봅시다. Cargo 프로젝트로 만들기 위해서 필요한 것들은 다음에 나열했습니다.

1. 당신의 소스를 정확한 폴더에 집어넣어 주십시오.
2. 이전에 만든 실행 파일을 지워 주십시오. _(윈도우라면 `main.exe`을, 다른 운영체제라면 `main` 을 지워 주시면 됩니다)_
3. Cargo 설정 파일을 생성합니다.

자, 시작해봅시다!

### 새로운 실행 파일과 소스 폴더를 생성하기

앞서, 터미널로 돌아가서 당신의 *hello_world* _(프로젝트 폴더)_ 폴더로 이동합니다. 그리고 다음의 명령어들을 실행합니다.

```bash
$ mkdir src
$ mv main.rs src/main.rs
$ rm main # or 'del main.exe' on Windows
```

카고는 소스파일들이 *src* 디렉터리에 있을 것이라 전제하기 때문에 먼저 그것부터 해결해야 합니다. 프로젝트의 최상위 디렉터리에는(이 경우는 *hello_world*) README, 라이센스 정보, 기타 코드랑 관련없는 것들만 남겨둡니다. 이렇게 해서 카고는 프로젝트를 깔끔하게 유지하는걸 도와줍니다. 만물에는 제자리가 있는 법이니까요.

이제 *main.rs* 파일을 *src* 디렉터리로 복사하고, `rustc` 명령어로 컴파일된 파일을 삭제합니다. 물론 윈도우에서는 `main`이 아니라 `main.exe`입니다.

이 예제에서는 실행파일을 만들기 때문에 소스파일 이름을 `main.rs`로 그대로 두었습니다. 실행파일이 아니라 라이브러리를 만들때는 파일 이름을 `lib.rs`로 해야 합니다. 이 전통은 카고가 성공적으로 컴파일하는데 사용되지만 원한다면 바꿀 수도 있습니다.

### 설정 파일 생성하기

다음에는 *hello_world* 디렉터리에 새 파일을 만들고 이름을 이렇게 짓습니다.
`Cargo.toml`.

`Cargo.toml` 안의 `C`가 대문자임에 주의하세요. 안그러면 카고가 설정파일을 인식하지 못합니다.

이 파일은 *[TOML]* 형식을 따릅니다. TOML은 INI와 비슷하지만 몇가지 장점이 있어서 카고의 설정 파일 형식으로 사용됩니다.

[TOML]: https://github.com/toml-lang/toml

이 파일을 대신해서, 다음의 것들을 입력해주세요.

```toml
[package]

name = "hello_world"
version = "0.0.1"
authors = [ "Your name " ]
```

첫째줄에서 `[package]`는 다음 구문들이 패키지의 설정이라는 것을 알려줍니다. 이 파일에 뭔가 다른 정보를 더하면 다른 섹션을 사용하게 되겠지만 지금은 그냥 패키지 설정 뿐입니다.

나머지 세 줄은 카고가 프로그램을 컴파일하는데 필요한 정보를 알려줍니다. 이름, 버전정보, 그리고 쓴 사람을요.

이 정보들을 *Cargo.toml* 파일에 쓰고 나면 저장해서 설정을 마치세요.

## Cargo프로젝트를 빌드하고 실행하기

*Cargo.toml* 파일이 프로젝트 루트 디렉터리에 있으면 Hello World 프로그램을 빌드하고 실행할 준비가 된겁니다! 그렇게 하려면 다음 명령어를 치세요.

```bash
$ cargo build
Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
$ ./target/debug/hello_world
Hello, world!
```

모두 잘 작동했다면, `Hello, world!`라는 문자열이 당신의 터미널에 출력될 것입니다.

당신은 방금 `cargo build` 명령어로 프로젝트를 빌드했고,
빌드한 결과물은 `./target/debug/hello_world`에 있을 것입니다. 하지만 사실 빌드한 후 빌드한 결과물을 확인, 실행하는 것은 `cargo run` 명령어로 간단히 할 수 있습니다.

```bash
$ cargo run
Running `target/debug/hello_world`
Hello, world!
```

이 예제가 프로젝트를 다시 빌드하지 않았다는 사실을 주목해주세요. 카고는 파일이 바뀌지 않았다는 것을 알아차리고는 그냥 바이너리를 실행했습니다. 만약 소스코드를 바꿨다면 카고는 실행하기 전에 프로젝트를 리빌드할거고 다음과 같은 메시지가 뜰 것입니다.

```bash
$ cargo run
Compiling hello_world v0.0.1 (file:///home/yourname/projects/hello_world)
Running `target/debug/hello_world`
Hello, world!
```

Cargo는 자동으로 어느 프로젝트 파일이 수정되었는지 확인하고, 수정된 코드만 다시 빌드합니다.

간단한 프로젝트에서 카고는 단순히 `rustc`를 여러 번 실행할 뿐입니다. 하지만 나중에는 유용하게 쓰일겁니다. 여러 개의 크레이트가 있는 복잡한 프로젝트는 카고가 빌드를 관리하게 냅두는게 훨씬 쉽습니다. 카고가 있으면 그냥 `cargo build`만 실행시키면 제대로 작동할 것입니다.

## 프로그램 릴리즈

프로그램이 마침내 배포될 때가 오면 프로젝트를 최적화 옵션을 켜고 컴파일하기 위해 `cargo build --release` 명령어를 칩니다. 이 최적화는 러스트 코드의 속도를 향상시키지만 이것을 켜 놓으면 컴파일이 더 오래걸립니다. 그렇기 때문에 개발을 위한 컴파일과 배포를 위한 컴파일이 따로 있는 것입니다.


## `Cargo.lock`은 무엇입니까?

`cargo build`
명령어를 실행시키는 것은 또한 *Cargo.lock*이라는 새로운 파일을 만듭니다. 그 내용은 다음과 같습니다.

```toml
[root]
name = "hello_world"
version = "0.0.1"
```

카고는 *Cargo.lock* 파일을 애플리케이션의 의존성을 추적하는데 사용합니다. 이게 Hello World 프로젝트의 *Cargo.lock* 파일입니다. 이 프로젝트는 의존성이 없기 때문에 파일이 텅 비어있습니다. 현실적으로 이 파일을 직접 만질 필요는 거의 없습니다. 그냥 카고가 작성하도록 냅두세요.

이게 답니다! 잘 따라왔다면 성공적으로 `hello_world`를 카고로 빌드할 수 있을 겁니다.

이 프로젝트는 무척 간단하지만 러스트 인생에서 사용할 툴의 대부분을 사용하고 있습니다. 사실상 대부분의 러스트 프로젝트를 시작할 때는 다음 명령어를 약간씩만 바꾼다고 볼 수 있습니다.

```bash
$ git clone someurl.com/foo
$ cd foo
$ cargo build
```

## 무작정 따라하는 Cargo프로젝트 만들기

앞의 길고 긴 방법은 너무나도 번거롭습니다. _당신도 공감하리라 믿습니다._ 하지만 사실, 당신은 앞서 보여드린 번거롭디번거로운 과정을 매 새 프로젝트를 시작 할 때마다 하지 않아도 됩니다. Cargo는 쉽고 빠르게 당신이 정확하게 개발을 시작할 수 있도록 프로젝트 폴더를 구성해줍니다.

새 Cargo 프로젝트를 생성하려면, `cargo new`명령어를 실행하면 됩니다.

```bash
$ cargo new hello_world --bin
```

이 프로젝트는 라이브러리가 아니라 실행 프로그램을 만들 것이기 때문에 `--bin` 옵션을 붙였습니다. 실행파일은 *바이너리*라고도 불립니다(유닉스 시스템의 `/usr/bin` 안에 있는 것처럼).

카고는 두 개의 파일과 하나의 디렉터리를 만들었습니다. `Cargo.toml` 파일과 *src* 디렉터리, 그리고 그 안에 들어있는 *main.rs* 파일입니다. 이것들이 익숙해보인다면, 우리가 방금 전 위에서 직접 만들었으니까 당연합니다.

이 결과물이 시작할 때 필요한 전부입니다. 먼저 `Cargo.toml` 파일을 열면 이렇게 되어있을 것입니다.

```toml
[package]

name = "hello_world"
version = "0.1.0"
authors = ["Your Name "]
```

카고는 *Cargo.toml*에 주어진 조건에 맞는 디폴트들과 `git` 전역 설정을 작성했을 것입니다. 카고는 또한 `hello_world` 디렉터리를 만들 때 `git` 레포지터리를 시작합니다.

`src/main.rs`에는 다음의 코드가 작성돼 있을 것입니다:

```rust
fn main() {
println!("Hello, world!");
}
```

Cargo는 당신을 위해서 "Hello world!"를 먼저 생성해 둘 것입니다. 이제 당신이 코딩할 차례입니다!

> 참고: Cargo에 대해 더 궁금하다면, 공식 [Cargo 문서][Cargo guide]를 참고 하시면 좋습니다.

[Cargo guide]: http://doc.crates.io/guide.html

# 마치며

이 챕터는 기본적으로 당신의 러스트와 함께하는 시간이 목적입니다. 자, 이제 당신은 충분히 러스트와 함께 쉬고 대화했으니, 이젠 러스트가 말할 차례입니다.

당신은 두 가지 선택지가 있습니다. 바로 [러스트와 함께하는 새로운 프로젝트][learnrust]를 시작하거나, 처음부터 [러스트의 문법][syntax]을 배우며 입문하는 것입니다. 많은 경험자들 _(사실 거의 모든 이 문서의 독자들)_ 러스트와 함께하는 새로운 프로젝트를 선호할 것입니다. 뭐 사정 다른 사람은 다른 선택지를 선택하게 되겠죠! 뭐, 저에게 당신이 무엇을 아는지 모르는지가 중요한가요. 당신이 원하는 대로 하시면 됩니다.

[learnrust]: learn-rust.html
[syntax]: syntax-and-semantics.html
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 } => ...
}
```

패턴은 아주 강력합니다. 잘 사용해보세요.
trait-objects
# 5.22. 트레잇 객체 (Trait Objects) - 75%

다형성과 관련된 코드가 실행될 때, 어떤 버전의 코드가 실행될지 결정하는 메카니즘이 필요합니다.
이것을 'dispatch' 라고 하며, 두 가지의 주요 형태가 있습니다: 정적 dispatch 와 동적 dispatch.
rust 는 정적 dispatch 를 선호하는데, 'trait objects' 라는 메커니즘을 통해서 동적 dispatch 역시 지원합니다.

## 배경

이 장에서 트레잇과 몇 개의 구현체가 필요합니다.
`Foo` 라는 간단한 코드를 만들어 봅시다. `String` 을 리턴하는 하나의 메소드를 갖고 있습니다.

```rust
trait Foo {
fn method(&self) -> String;
}
```

`u8`과 `String` 에 대해 이 트레잇을 구현 할 것입니다.

```rust
# trait Foo { fn method(&self) -> String; }
impl Foo for u8 {
fn method(&self) -> String { format!("u8: {}", *self) }
}

impl Foo for String {
fn method(&self) -> String { format!("string: {}", *self) }
}
```

## 정적 dispatch

정적 dispatch 를 수행하기 위해, 이 트레잇과 트레잇 바운드를 사용할 수 있습니다:

```rust
# trait Foo { fn method(&self) -> String; }
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
fn do_something(x: T) {
x.method();
}

fn main() {
let x = 5u8;
let y = "Hello".to_string();

do_something(x);
do_something(y);
}
```

여기서 rust 는 정적 dispatch 를 수행하기 위해 단형화(monomorphization)를 사용합니다.
이 말은 rust 는 `u8` 과 `String` 을 위한 특별한 버전의 `do_something()`을 만들고, 이 메소드에 대한 호출부들을 이 구체화된 함수들에 대한 호출로 바꾼다는 것을 의미 합니다. 다르게 말하면, rust 는 이렇게 생성 합니다:

```rust
# trait Foo { fn method(&self) -> String; }
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }
fn do_something_u8(x: u8) {
x.method();
}

fn do_something_string(x: String) {
x.method();
}

fn main() {
let x = 5u8;
let y = "Hello".to_string();

do_something_u8(x);
do_something_string(y);
}
```

이것은 아주 큰 장점을 지니는데: 함수 호출하는 부분을 컴파일 타임에 알 수 있기 때문에, 정적 dispatch 는 함수 호출을 인라인 할 수 있으며, 인라인은 좋은 최적화의 핵심 입니다. 정적 dispatch 는 빠르지만 단점이 있습니다: 바이너리에 각 타입 별로 같은 함수의 복사본들이 있기 때문에 코드가 커집니다. (code bloat)

뿐만 아니라, 컴파일러는 완벽하지 않기 때문에 "최적화" 코드가 더 느려질 수 도 있습니다.
예를 들면, 너무 과하게 함수가 인라인되면 명령어 캐시를 넘칠 수 있습니다. (캐시가 우리 주변의 모든 것을 지배합니다)
이것이 `#[inline]`과 `#[inline(always)]` 이 신중하게 사용되어야 하는 이유이고, 동적 dispatch 가 가끔 더 효율적인 이유 입니다.

그러나, 일반적인 경우 정적 dispatch 를 사용하는 것이 더 효율적이고, 항상 정적으로 dispatch 되는 wrapper 함수가 동적 dispatch 를 수행하도록 할 수 있습니다. 반대로는 되지 않으며, 정적 호출이 더 유연하다는 것을 의미 합니다.
표준 라이브러리는 이런 이유로 가능하면 정적으로 dispatch 하도록 하고 있습니다.

## 동적 dispatch

Rust 는 ‘트레잇 객채(trait objects)’ 라는 기능을 통해 동적 dispatch 를 제공 합니다.
트레잇 객체는 `&Foo` 혹은 `Box` 와 같이 주어진 트레잇을 구현한 *어떤* 타입의 값을 저장하는 평범한 값들이며, 정확한 타입은 런타입에 결정 될 수 있습니다.

트레잇 객체는 트레잇을 구현한 구체적인 타입에 대한 포인터를 *캐스팅* 하거나 (예. `&x as &Foo`) *강제(coercing)* 해서 (예. `&Foo` 가 파라미터로 정의된 함수에 대해 인자로 `&x` 를 사용) 얻을 수 있습니다.

이러한 트레잇 객체에 대한 강제(coercion)나 캐스팅은 `&mut Foo` 나 `Box` 에 대한 포인터인 `&mut T`, `Box` 에 대해서도 모두 그 순간에 동작합니다. 강제와 캐스팅은 동일합니다.

이 작업은 특정 포인터의 타입에 대한 컴파일러의 지식을 ‘지우는’ 것 처럼 보입니다. 이런 이유로 트레잇 객체는 가끔 ‘타입 지우개(type erasure)’ 로 불립니다.

위 예제로 돌아가면, 트레잇 객체들을 동일한 트래잇으로 캐스팅 함으로써 동적 dispatch 를 수행할 수 있습니다:

```rust
# trait Foo { fn method(&self) -> String; }
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }

fn do_something(x: &Foo) {
x.method();
}

fn main() {
let x = 5u8;
do_something(&x as &Foo);
}
```

혹은 강제하기:

```rust
# trait Foo { fn method(&self) -> String; }
# impl Foo for u8 { fn method(&self) -> String { format!("u8: {}", *self) } }
# impl Foo for String { fn method(&self) -> String { format!("string: {}", *self) } }

fn do_something(x: &Foo) {
x.method();
}

fn main() {
let x = "Hello".to_string();
do_something(&x);
}
```

트레잇 객체를 받는 함수는 `Foo` 를 구현한 각각의 타입들에 대해서 구체화 하지 않습니다: 항상 그렇지는 않지만 하나의 복사본이 생성되고 적은 코드 블로트가 발생합니다. 그러나 더 느린 가상함수 호출 비용이 발생하게 되고, 효과적으로 인라이닝(inlining) 하고 관련된 최적화가 발생하는 것을 방해합니다.

### 왜 포인터인가요?

rust 는 많은 관리되는 언어(managed language)와 다르게 기본적으로 포인터를 사용해서 객체를 할당하지 않기 때문에 타입은 다른 크기를 갖을 수 있습니다.
함수의 인자로 값을 넘기는 경우, 그리고 스택(stack)에서 값을 이동하거나 저장하기 위해 힙(heap)에 할당(그리고 해제)하는 것들과 같은 일을 하는데 있어서, 컴파일 타임에 값의 크기를 아는 것은 중요 합니다.

`Foo` 와 같은 경우, 최소한 `String` (24 바이트) 혹은 `u8` (1 바이트) 크기인 값을 필요로 할 것이며, `Foo`를 구현하는 종속적인 크레이트에서의 어떤 타입이던지 역시 최소 몇 바이트가 되어야 할 것입니다.

값을 포인터를 통해 할당한다는 것은 트레잇 객체를 넘기는 경우에 한해서는 값의 크기는 유의미하지 않다는 것이며, 단지 포인터 자체의 크기만 의미 있다는 것입니다.

### 표현(Representation)

트레잇 객체를 사용한 트리잇의 메소드들은 전통적으로 (컴파일러에 의해 생성되고 관리되는) 'vtable' 이라고 하는 함수 포인터들의 특별한 기록들을 통해서 호출할 수 있습니다.

트레잇 객체는 단순하기도 하고 복잡하기도 합니다: 그것들의 핵심 표현이나 모양(layout)은 아주 간단합니다만, 이상한 에러 메세지들도 있고 확인해봐야 할 놀라운 동작들도 있습니다.

트레잇 객체의 런타임 표현을 간단하게 살펴보도록 합시다. `std::raw` 모듈은 복잡한 빌트인 타입들과 같은 모양을 갖는 구조체들을 갖고 있습니다. [including trait objects][stdraw]:

```rust
# mod foo {
pub struct TraitObject {
pub data: *mut (),
pub vtable: *mut (),
}
# }
```

[stdraw]: ../std/raw/struct.TraitObject.html

즉, `&Foo` 과 같은 트리잇 객체는 'data' 포인터와 'vtable' 포인터로 구성됩니다.

data 포인터는 트리엣 객체가 저장하고 있는 (어떤 알려지지 않은 타입 `T`의) 데이터를 가르키고 있으며, vtable 포인터는 `T` 에 대한 `Foo` 의 구현에 대응되는 vtable(가상 메소드 테이블)을 가르 킵니다.

vtable 은 본질적으로는 구현된 각 메소드들에 대한 구체적인 기계 코드 조각을 가르키는 함수 포인터들을 갖고 있는 구조체 입니다. `trait_object.method()` 와 같은 메소드 호출은 vtable 에서 정확한 포인터를 가져와서 동적으로 호출 할 것입니다. 예를 들면:

```rust,ignore
struct FooVtable {
destructor: fn(*mut ()),
size: usize,
align: usize,
method: fn(*const ()) -> String,
}

// u8:

fn call_method_on_u8(x: *const ()) -> String {
// 컴파일러는 이 함수가 u8 을 가르키는 `x` 에 대해서만 호출되도록
// 보장합니다.
let byte: &u8 = unsafe { &*(x as *const u8) };

byte.method()
}

static Foo_for_u8_vtable: FooVtable = FooVtable {
destructor: /* compiler magic */,
size: 1,
align: 1,

// cast to a function pointer
method: call_method_on_u8 as fn(*const ()) -> String,
};


// String:

fn call_method_on_String(x: *const ()) -> String {
// 컴파일러는 이 함수가 String 을 가르키는 `x` 에 대해서만 호출되도록
// 보장합니다.
let string: &String = unsafe { &*(x as *const String) };

string.method()
}

static Foo_for_String_vtable: FooVtable = FooVtable {
destructor: /* compiler magic */,
// values for a 64-bit computer, halve them for 32-bit ones
size: 24,
align: 8,

method: call_method_on_String as fn(*const ()) -> String,
};
```
각 vtable 의 `destructor` 필드는 vtable 의 타입에 대한 리소스들을 정리 하는데 사용되는 함수를 가르킵니다, `u8` 은 사소하지만, `String` 인 경우는 메모리를 해제 할 것입니다. 이것은 `Box` 와 같이 트레잇 객체를 소유하는 경우, `Box` 에 대한 할당과 스코프를 벗어났을 때 내부 타입을 정리 하기 위해 필요합니다. `size` 와 `align` 필드들은 지워진 타입에 대한 크기와 정렬(alignment) 요구사항들을 저장합니다; 이것들은 기본적으로 소멸자(destructor)에 포함되기 때문에 지금은 사용되지 않지만, 트레잇 객체는 계속해서 더 유연하게 만들어 지기 때문에 나중에는 사용될 것 입니다.

`Foo` 를 구현한 몇 개의 값들이 있다고 가정할 때, `Foo` 트레잇 객체의 구조에 대한 명시적인 형태나 사용은 약간 아래와 비슷할 것입니다. (타입 불일치는 무시: 어쨌든 모두 포인터):

```rust,ignore
let a: String = "foo".to_string();
let x: u8 = 1;

// let b: &Foo = &a;
let b = TraitObject {
// store the data
data: &a,
// store the methods
vtable: &Foo_for_String_vtable
};

// let y: &Foo = x;
let y = TraitObject {
// store the data
data: &x,
// store the methods
vtable: &Foo_for_u8_vtable
};

// b.method();
(b.vtable.method)(b.data);

// y.method();
(y.vtable.method)(y.data);
```

## Object Safety
Object 보호

모든 트레잇이 트레잇 객체를 만들어낼 수 있는 것은 아니다. 예를 들어, vector들은 `Clone`을 구현하고 있지만, 트레잇 객체를 만들고자 한다면:

Not every trait can be used to make a trait object. For example, vectors implement
`Clone`, but if we try to make a trait object:

```ignore
let v = vec![1, 2, 3];
let o = &v as &Clone;
```

우리는 에러를 받게 된다:
We get an error:

```text
error: cannot convert to a trait object because trait `core::clone::Clone` is not object-safe [E0038]
let o = &v as &Clone;
^~
note: the trait cannot require that `Self : Sized`
let o = &v as &Clone;
^~
```

해당 에러는 `Clone`이 '객체-안전'하지 않다고 말한다. 오직 객체-안전한 트레잇만이 트레잇 객체를 만들 수 있다. 다음의 사항들을 만족할 때 트레잇이 객체-앉전 하다고 할 수 있다:
The error says that `Clone` is not ‘object-safe’. Only traits that are
object-safe can be made into trait objects. A trait is object-safe if both of
these are true:

* `Self: Sized`가 필요치 않은 트레잇
* 소유한 모든 메소드가 객체-안전해야 함.
* the trait does not require that `Self: Sized`
* all of its methods are object-safe

그렇다면 어떻게 객체-안전한 메소드를 만들까? 모든 메소드가 `Self: Sized`를 반드시 요구하던가 다음의 내용들을 만족해야 한다.:
So what makes a method object-safe? Each method must require that `Self: Sized`
or all of the following:

* 어떤 타입 인자도 가져서는 안된다.
* `Self`를 사용해서는 안된다.
* must not have any type parameters
* must not use `Self`

휘유~! 살펴본 바와 같이, 이들 룰에 대한 것의 대부분은 `Self`에 대한 내용이다.
"특별한 경우를 제외하고, 트레잇의 메소드에서 `Self`를 사용하는 것은 객체-안전하지 않다." - 좋은 직관.
Whew! As we can see, almost all of these rules talk about `Self`. A good intuition
is “except in special circumstances, if your trait’s method uses `Self`, it is not
object-safe.”
ufcs
# 5.24. 전역 함수 사용법 (Universal Function Call Syntax) - 0%

종종, 함수들은 동일한 이름을 갖게 된다. 다음 코드를 살펴보자:
Sometimes, functions can have the same names. Consider this code:

```rust
trait Foo {
fn f(&self);
}

trait Bar {
fn f(&self);
}

struct Baz;

impl Foo for Baz {
fn f(&self) { println!("Baz’s impl of Foo"); }
}

impl Bar for Baz {
fn f(&self) { println!("Baz’s impl of Bar"); }
}

let b = Baz;
```

우리가 `b.f()`를 호출하고자 하면, 다음의 에러를 얻게 된다:
If we were to try to call `b.f()`, we’d get an error:

```text
error: multiple applicable methods in scope [E0034]
b.f();
^~~
note: candidate #1 is defined in an impl of the trait `main::Foo` for the type
`main::Baz`
fn f(&self) { println!("Baz’s impl of Foo"); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate #2 is defined in an impl of the trait `main::Bar` for the type
`main::Baz`
fn f(&self) { println!("Baz’s impl of Bar"); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

```

우리가 필요한 메소드가 어떤 것인지 분명히 할 필요가 있다. 이런 기능을 '우주적(전역) 함수 호출 문법', 이라고 부르고, 다음과 같이 사용한다:
We need a way to disambiguate which method we need. This feature is called
‘universal function call syntax’, and it looks like this:

```rust
# trait Foo {
# fn f(&self);
# }
# trait Bar {
# fn f(&self);
# }
# struct Baz;
# impl Foo for Baz {
# fn f(&self) { println!("Baz’s impl of Foo"); }
# }
# impl Bar for Baz {
# fn f(&self) { println!("Baz’s impl of Bar"); }
# }
# let b = Baz;
Foo::f(&b);
Bar::f(&b);
```

나눠서 살펴보자.
Let’s break it down.

```rust,ignore
Foo::
Bar::
```

호출문의 절반은 두 트레잇들이다: `Foo`와 `Bar`. 이들의 끝 부분이 실제로 어떤 일을 할지를 결정한다: 러스트는 사용된 트레잇 이름에서 호출하게 된다.
These halves of the invocation are the types of the two traits: `Foo` and
`Bar`. This is what ends up actually doing the disambiguation between the two:
Rust calls the one from the trait name you use.

```rust,ignore
f(&b)
```

우리가 메소드를 `b.f()`같이 [method syntax][methodsyntax]를 사용하여 호출하게 되면, 러스트는 `f()`가 `&self`를 취할 경우 자동으로 `b`를 대여한다. 이번 경우에는, 러스트는 하지 않을 것이고, 그렇기에 우리는 `&b`를 명시적으로 전달할 필요가 있다.
When we call a method like `b.f()` using [method syntax][methodsyntax], Rust
will automatically borrow `b` if `f()` takes `&self`. In this case, Rust will
not, and so we need to pass an explicit `&b`.

[methodsyntax]: method-syntax.html

# Angle-bracket Form
꺾쇄 괄호 형태( <> )

이번에 얘기하고자 하는 UFCS(Universal Function Call Syntax : 전역 함수 호출 문법)이다:

The form of UFCS we just talked about:

```rust,ignore
Trait::method(args);
```

이는 줄여쓴 것이다. 어떤 상황에는 확장된 형식을 사용해야 할 필요가 있다.
Is a short-hand. There’s an expanded form of this that’s needed in some
situations:

```rust,ignore
::method(args);
```

`<>::` 문법은 타입의 힌트를 제공한다. `<>`안에 타입이 들어가게 된다. 이번 경우에 타입은 `Type as Trait`이고, `Trait`의 `method` 를 호출하는 버전을 보여주고자 한다. `as Trait` 부분은 부가적인 것으로 타입이 모호하지 않다면 빼도 된다. 꺾쇄 괄호 외엔 줄여쓴 형태와 같다.
The `<>::` syntax is a means of providing a type hint. The type goes inside
the `<>`s. In this case, the type is `Type as Trait`, indicating that we want
`Trait`’s version of `method` to be called here. The `as Trait` part is
optional if it’s not ambiguous. Same with the angle brackets, hence the
shorter form.

여기 긴 형태의 예제가 있다.
Here’s an example of using the longer form.

```rust
trait Foo {
fn clone(&self);
}

#[derive(Clone)]
struct Bar;

impl Foo for Bar {
fn clone(&self) {
println!("Making a clone of Bar");

::clone(self);
}
}
```

이는 `Foo` 대신 `Clone` 트레잇의 `clone()`을 호출할 것이다.
This will call the `Clone` trait’s `clone()` method, rather than `Foo`’s.