Merge changes from hanbum into master

sarojaba authored
revision 337887ecd406b654c924325ea15fda8ea21b87e1
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() {}
```