• 59e24d0c386229a160c639c88b6f1c07?s=80&d=mm

    Changes from AinL

    AinL - about 3 years ago (Mar 23, 2016, 7:15 PM)
    update getting-start.md
  • Changes have been accepted Merged
      Looks like something's not quite right here.. We've been notified of the issue, and will get back to you soon.
      About
      ### Rust 문서 한글화 프로젝트

      - 본 프로젝트는 Mozilla에서 개발한 Rust 언어의 문서를 한글화하는 프로젝트입니다.
      - 현재 Book 1.4.0에서 [Book 1.5.0](http://doc.rust-lang.org/stable/book/)으로 업데이트 중입니다. [Markdown](http://daringfireball.net/projects/markdown/basics) 포맷을 기본으로 합니다.
      - 기본적인 문장체는 높임말로 끝나기만 하면 됩니다. 원문의 의도만 바뀌지 않는다면 재밌게 의역도 상관없습니다. IT 번역에 대해서는 [어서 와! 번역은 처음이지?](http://www.slideshare.net/wegra/ss-52826286)에 자세히 안내되어 있습니다.
      - 참여를 원하시는 분께서는 [sarojaba](mailto://sarojaba@gmail.com) 에게 연락주시기 바랍니다.
      - 나중에 [rust](https://github.com/mozilla/rust) 프로젝트에 올릴 수 있을까요?
      - 인터뷰: ['요즘 뜨는 4대 프로그래밍 언어, 이렇게 배워보세요.'](https://www.bloter.net/archives/230851)

      - 최근 활발한 참여자
      - [djKooks](https://www.penflip.com/djKooks)
      - [handrake](https://www.penflip.com/handrake)
      - [minujeong](https://www.penflip.com/minujeong)
      - [jade.kim](https://www.penflip.com/jenix21)
      - [jaeju_Kim](https://www.penflip.com/Jaeju_Kim)
      - [SoonBin](https://www.penflip.com/SoonBin)

      - 한글화 미완료 챕터 목록(작성중)
      - [4.4. 문서화 (Documentation)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/documentation.md) - 15%
      - [4.8. 외부 함수 인터페이스 (Foreign Function Interface)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/ffi.md) - 0%
      - [5.13. 열거형 (Enums)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/enums.md) - 0%
      concordance
      # 9. 용어 색인 (Concordance)

      * 이 페이지는 Rust 한글화 프로젝트에서 사용되는 용어들의 영문과 국문을 일대일로 표기해놓은 가이드입니다.
      * 번역하시면서 새로운 용어가 나오면 추가해주세요. 좀 더 적절한 대체 용어가 있다면 구성원들의 의견을 모아 반영합니다.
      * 알파벳 순으로 표기합니다.
      * [정보통신용어사전](http://word.tta.or.kr/terms/terms.jsp), [텀즈](http://www.terms.co.kr/), [Joinc 컴퓨터 용어사전](http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/12), [정보통신기술용어해석](http://www.ktword.co.kr/) 등을 참조하세요.

      ## A - G

      * address - 주소
      * allocate - 할당하다
      * arm (match) - 가지
      * associated functions - 연관 함수
      * binding - 바인딩
      * borrowing - 빌림
      * bound - 바운드
      * Cargo - 카고
      * Crate - 크레이트
      * compile - 컴파일
      * concurrent program - 동시처리 프로그램
      * concurrency - 동시성
      * dynamic language - 동적 언어
      * exterior mutability - 외적 가변성
      * Field-level mutability - 필드 단위 가변성
      * function - 함수
      * garbage collector - 가비지 콜렉터

      ## H - N

      * heap - 힙
      * immutable - 변경할 수 없는, 불변
      * immutable - 불변
      * input - 입력
      * interior mutability - 내적 가변성
      * iterator - 반복자
      * lifetime - 수명
      * lifetime elision - 수명의 생략
      * LIFO - LIFO
      * macro - 매크로
      * memory safety - 메모리 보호, 메모리 보호처리
      * mutable - 변경할 수 있는
      * mutable - 가변
      * mutability - 가변성

      ## O - Z

      * output - 출력
      * ownership - 소유권
      * parellelism - 병렬성
      * pointer - 포인터
      * Rust - 러스트
      * semantics - 구문
      * signiture - 시그니처
      * stack - 스택
      * syntax - 의미
      * testing- 테스팅
      * variable - 변수
      * vector - 벡터
      * verification - 검증
      * zero-cost abstractions - 무비용 추상화
      conditional-compilation
      # 4.3. 조건부 컴파일 (Conditional Compilation) - 70%

      Rust는 컴파일러에게 전달되는 플래그 값에 기반해 코드를 컴파일하도록 해주는 `#[cfg]`라는 특별한 속성을 가지고 있습니다. 여기에는 두가지 형식이 있습니다.

      ```rust
      #[cfg(foo)]
      # fn foo() {}

      #[cfg(bar = "baz")]
      # fn bar() {}
      ```

      또 몇가지 helper 도 가지고 있습니다.

      ```rust
      #[cfg(any(unix, windows))]
      # fn foo() {}

      #[cfg(all(unix, target_pointer_width = "32"))]
      # fn bar() {}

      #[cfg(not(foo))]
      # fn not_foo() {}
      ```

      이것들은 임의로 겹칠 수도 있습니다.

      ```rust
      #[cfg(any(not(unix), all(target_os="macos", target_arch = "powerpc")))]
      # fn foo() {}
      ```

      만약 Cargo를 사용한다면, `Cargo.toml`의 [`[features]` [section][features] 속성값을 통해 이 기능들을 사용할 지 여부를 설정할 수 있습니다.

      [features]: http://doc.crates.io/manifest.html#the-%5Bfeatures%5D-section

      ```toml
      [features]
      # no features by default
      default = []

      # The “secure-password” feature depends on the bcrypt package.
      secure-password = ["bcrypt"]
      ```

      위와 같이 구현하면, Cargo는 flag값들을 `rustc`로 전달합니다.

      ```text
      --cfg feature="${feature_name}"
      ```

      이렇게 정의된 `cfg` flag값들은 어떤 속성들이 활성화 되어야 하고, 이를 통해 어떤 코드들이 컴파일 되어야 하는지를 결정하게 됩니다. 아래 코드를 살펴보도록 하겠습니다.

      ```rust
      #[cfg(feature = "foo")]
      mod foo {
      }
      ```

      위 코드를 `cargo build --features "foo"`로 컴파일 할 경우, `--cfg feature="foo"`플래그값을 `rustc`로 전달하고 결과물에는 `mod foo`가 포함되게 됩니다. 반대로, 일반적인 `cargo build`로 컴파일할 경우에는 어떤 flag값도 전달되지 않으며, 따라서 `foo`모듈도 존재하지 않습니다.

      # cfg_attr

      `cfg_attr`라는 명령어를 사용해서 `cfg` 에 기반한 다른 속성들을 설정하는 것도 가능합니다.

      ```rust
      #[cfg_attr(a, b)]
      ```

      `a`가 `cfg` 속성에 설정되어 있을 경우, 위 코드는 `#[b]`와 동일한 결과를 출력하며, 그 이외의 차이점은 없습니다.

      # cfg!

      `cfg!` [syntax extension][compilerplugins] 를 아래와 같은 방식으로 자신의 코드에 추가할 수 있습니다.

      ```rust
      if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
      println!("Think Different!");
      }
      ```

      [compilerplugins]: compiler-plugins.html

      프로젝트의 설정값에 따라 위 선택문들은 컴파일 중 `true` 나 `false`로 대체됩니다.

      crates-and-modules
      # 5.25. Crates and Modules크레이트들과(Crate) 모듈들(Module) - 0%

      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

      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.

      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.

      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 |
      +-----------+
      ```

      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.

      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` is our crate root, corresponding to the `phrases` in our diagram
      above.

      # Defining Modules

      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 {
      }
      }
      ```

      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 (`{}`).

      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`.

      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` 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

      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;
      ```

      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.

      Note that in these files, you don’t need to re-declare the module: that’s
      already been done with the initial `mod` declaration.

      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` is our crate root, and looks like this:

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

      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;
      ```

      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!

      The contents of `src/english/greetings.rs` and `src/japanese/farewells.rs` are
      both empty at the moment. Let’s add some functions.

      Put this in `src/english/greetings.rs`:

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

      Put this in `src/english/farewells.rs`:

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

      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.

      Put this in `src/japanese/farewells.rs`:

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

      (This is ‘Sayōnara’, if you’re curious.)

      Now that we have some functionality in our crate, let’s try to use it from
      another crate.

      # Importing External Crates

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

      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());
      }
      ```

      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.

      (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;`.)

      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
      ```

      By default, everything is private in Rust. Let’s talk about this in some more
      depth.

      # Exporting a Public Interface

      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());
      }
      ```

      In our `src/lib.rs`, let’s add `pub` to the `english` module declaration:

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

      And in our `src/english/mod.rs`, let’s make both `pub`:

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

      In our `src/english/greetings.rs`, let’s add `pub` to our `fn` declaration:

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

      And also in `src/english/farewells.rs`:

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

      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` 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`.

      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`

      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());
      }
      ```

      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());
      }
      ```

      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`.
      ```

      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`

      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.

      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());
      }
      ```

      Then, modify your `src/lib.rs` to make the `japanese` mod public:

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

      Next, make the two functions public, first in `src/japanese/greetings.rs`:

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

      And then in `src/japanese/farewells.rs`:

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

      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;
      ```

      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.

      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::*`.

      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.

      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

      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?

      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.

      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.

      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;
      ```
      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.
      error-handling
      # 4.7. 오류 처리 (Error Handling) - 0%

      Like most programming languages, Rust encourages the programmer to handle
      errors in a particular way. Generally speaking, error handling is divided into
      two broad categories: exceptions and return values. Rust opts for return
      values.
      수많은 프로그래밍 언어들이 그렇듯, 러스트는 프로그래머가 오류를 처리할 수 있는 방법을 제공합니다. 일반적으로 말하길, 오류 처리는 크게 두가지 분류로 나뉜다고 일커집니다: 첫쩨, 예외와 변수 리턴. 둘째, 변수 리턴을 위한 러스트 OPT

      이 쳅터에서는, 크고 강려크한 당신의 에러들과 싸울 수 있는 방비책을 소개 할것입니다.

      In this chapter, we intend to provide a comprehensive treatment of how to deal
      with errors in Rust. More than that, we will attempt to introduce error handling
      one piece at a time so that you'll come away with a solid working knowledge of
      how everything fits together.

      When done naïvely, error handling in Rust can be verbose and annoying. This
      chapter will explore those stumbling blocks and demonstrate how to use the
      standard library to make error handling concise and ergonomic.

      # Table of Contents목차

      This chapter is very long, mostly because we start at the very beginning with
      sum types and combinators, and try to motivate the way Rust does error handling
      incrementally. As such, programmers with experience in other expressive type
      systems may want to jump around.

      * [The Basics](#the-basics)
      * [Unwrapping explained](#unwrapping-explained)
      * [The `Option` type](#the-option-type)
      * [Composing `Option<T>` values](#composing-optiont-values)
      * [The `Result` type](#the-result-type)
      * [Parsing integers](#parsing-integers)
      * [The `Result` type alias idiom](#the-result-type-alias-idiom)
      * [A brief interlude: unwrapping isn't evil](#a-brief-interlude-unwrapping-isnt-evil)
      * [Working with multiple error types](#working-with-multiple-error-types)
      * [Composing `Option` and `Result`](#composing-option-and-result)
      * [The limits of combinators](#the-limits-of-combinators)
      * [Early returns](#early-returns)
      * [The `try!` macro](#the-try-macro)
      * [Defining your own error type](#defining-your-own-error-type)
      * [Standard library traits used for error handling](#standard-library-traits-used-for-error-handling)
      * [The `Error` trait](#the-error-trait)
      * [The `From` trait](#the-from-trait)
      * [The real `try!` macro](#the-real-try-macro)
      * [Composing custom error types](#composing-custom-error-types)
      * [Advice for library writers](#advice-for-library-writers)
      * [Case study: A program to read population data](#case-study-a-program-to-read-population-data)
      * [Initial setup](#initial-setup)
      * [Argument parsing](#argument-parsing)
      * [Writing the logic](#writing-the-logic)
      * [Error handling with `Box<Error>`](#error-handling-with-boxerror)
      * [Reading from stdin](#reading-from-stdin)
      * [Error handling with a custom type](#error-handling-with-a-custom-type)
      * [Adding functionality](#adding-functionality)
      * [The short story](#the-short-story)

      # The Basics기본

      You can think of error handling as using *case analysis* to determine whether
      a computation was successful or not. As you will see, the key to ergonomic error
      handling is reducing the amount of explicit case analysis the programmer has to
      do while keeping code composable.

      Keeping code composable is important, because without that requirement, we
      could [`panic`](../std/macro.panic!.html) whenever we
      come across something unexpected. (`panic` causes the current task to unwind,
      and in most cases, the entire program aborts.) Here's an example:

      ```rust,should_panic
      // Guess a number between 1 and 10.
      // If it matches the number we had in mind, return true. Else, return false.
      fn guess(n: i32) -> bool {
      if n < 1 || n > 10 {
      panic!("Invalid number: {}", n);
      }
      n == 5
      }

      fn main() {
      guess(11);
      }
      ```

      If you try running this code, the program will crash with a message like this:

      ```text
      thread '<main>' panicked at 'Invalid number: 11', src/bin/panic-simple.rs:5
      ```

      Here's another example that is slightly less contrived. A program that accepts
      an integer as an argument, doubles it and prints it.

      ```rust,should_panic
      use std::env;

      fn main() {
      let mut argv = env::args();
      let arg: String = argv.nth(1).unwrap(); // error 1
      let n: i32 = arg.parse().unwrap(); // error 2
      println!("{}", 2 * n);
      }
      ```

      If you give this program zero arguments (error 1) or if the first argument
      isn't an integer (error 2), the program will panic just like in the first
      example.

      You can think of this style of error handling as similar to a bull running
      through a china shop. The bull will get to where it wants to go, but it will
      trample everything in the process.

      ## Unwrapping explained

      In the previous example, we claimed
      that the program would simply panic if it reached one of the two error
      conditions, yet, the program does not include an explicit call to `panic` like
      the first example. This is because the
      panic is embedded in the calls to `unwrap`.

      To “unwrap” something in Rust is to say, “Give me the result of the
      computation, and if there was an error, just panic and stop the program.”
      It would be better if we just showed the code for unwrapping because it is so
      simple, but to do that, we will first need to explore the `Option` and `Result`
      types. Both of these types have a method called `unwrap` defined on them.

      ## The `Option` type형식

      The `Option` type is
      [defined in the standard library][1]:

      ```rust
      enum Option<T> {
      None,
      Some(T),
      }
      ```

      The `Option` type is a way to use Rust's type system to express the
      *possibility of absence*. Encoding the possibility of absence into the type
      system is an important concept because it will cause the compiler to force the
      programmer to handle that absence. Let's take a look at an example that tries
      to find a character in a string:

      ```rust
      // Searches `haystack` for the Unicode character `needle`. If one is found, the
      // byte offset of the character is returned. Otherwise, `None` is returned.
      fn find(haystack: &str, needle: char) -> Option<usize> {
      for (offset, c) in haystack.char_indices() {
      if c == needle {
      return Some(offset);
      }
      }
      None
      }
      ```

      Notice that when this function finds a matching character, it doen't just
      return the `offset`. Instead, it returns `Some(offset)`. `Some` is a variant or
      a *value constructor* for the `Option` type. You can think of it as a function
      with the type `fn<T>(value: T) -> Option<T>`. Correspondingly, `None` is also a
      value constructor, except it has no arguments. You can think of `None` as a
      function with the type `fn<T>() -> Option<T>`.

      This might seem like much ado about nothing, but this is only half of the
      story. The other half is *using* the `find` function we've written. Let's try
      to use it to find the extension in a file name.

      ```rust
      # fn find(_: &str, _: char) -> Option<usize> { None }
      fn main() {
      let file_name = "foobar.rs";
      match find(file_name, '.') {
      None => println!("No file extension found."),
      Some(i) => println!("File extension: {}", &file_name[i+1..]),
      }
      }
      ```

      This code uses [pattern matching][1] to do *case
      analysis* on the `Option<usize>` returned by the `find` function. In fact, case
      analysis is the only way to get at the value stored inside an `Option<T>`. This
      means that you, as the programmer, must handle the case when an `Option<T>` is
      `None` instead of `Some(t)`.

      But wait, what about `unwrap` used in [`unwrap-double`](#code-unwrap-double)?
      There was no case analysis there! Instead, the case analysis was put inside the
      `unwrap` method for you. You could define it yourself if you want:

      ```rust
      enum Option<T> {
      None,
      Some(T),
      }

      impl<T> Option<T> {
      fn unwrap(self) -> T {
      match self {
      Option::Some(val) => val,
      Option::None =>
      panic!("called `Option::unwrap()` on a `None` value"),
      }
      }
      }
      ```

      The `unwrap` method *abstracts away the case analysis*. This is precisely the thing
      that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that
      `unwrap` is not composable: it is the bull in the china shop.

      ### Composing `Option<T>` values변수들을 사용하기

      In [`option-ex-string-find`](#code-option-ex-string-find-2)
      we saw how to use `find` to discover the extension in a file name. Of course,
      not all file names have a `.` in them, so it's possible that the file name has
      no extension. This *possibility of absence* is encoded into the types using
      `Option<T>`. In other words, the compiler will force us to address the
      possibility that an extension does not exist. In our case, we just print out a
      message saying as such.

      Getting the extension of a file name is a pretty common operation, so it makes
      sense to put it into a function:

      ```rust
      # fn find(_: &str, _: char) -> Option<usize> { None }
      // Returns the extension of the given file name, where the extension is defined
      // as all characters proceding the first `.`.
      // If `file_name` has no `.`, then `None` is returned.
      fn extension_explicit(file_name: &str) -> Option<&str> {
      match find(file_name, '.') {
      None => None,
      Some(i) => Some(&file_name[i+1..]),
      }
      }
      ```

      (Pro-tip: don't use this code. Use the
      [`extension`](../std/path/struct.Path.html#method.extension)
      method in the standard library instead.)

      The code stays simple, but the important thing to notice is that the type of
      `find` forces us to consider the possibility of absence. This is a good thing
      because it means the compiler won't let us accidentally forget about the case
      where a file name doesn't have an extension. On the other hand, doing explicit
      case analysis like we've done in `extension_explicit` every time can get a bit
      tiresome.

      In fact, the case analysis in `extension_explicit` follows a very common
      pattern: *map* a function on to the value inside of an `Option<T>`, unless the
      option is `None`, in which case, just return `None`.

      Rust has parametric polymorphism, so it is very easy to define a combinator
      that abstracts this pattern:

      ```rust
      fn map<F, T, A>(option: Option<T>, f: F) -> Option<A> where F: FnOnce(T) -> A {
      match option {
      None => None,
      Some(value) => Some(f(value)),
      }
      }
      ```

      Indeed, `map` is [defined as a method][2] on `Option<T>` in the standard library.

      Armed with our new combinator, we can rewrite our `extension_explicit` method
      to get rid of the case analysis:

      ```rust
      # fn find(_: &str, _: char) -> Option<usize> { None }
      // Returns the extension of the given file name, where the extension is defined
      // as all characters proceding the first `.`.
      // If `file_name` has no `.`, then `None` is returned.
      fn extension(file_name: &str) -> Option<&str> {
      find(file_name, '.').map(|i| &file_name[i+1..])
      }
      ```

      One other pattern that we find is very common is assigning a default value to
      the case when an `Option` value is `None`. For example, maybe your program
      assumes that the extension of a file is `rs` even if none is present. As you
      might imagine, the case analysis for this is not specific to file
      extensions - it can work with any `Option<T>`:

      ```rust
      fn unwrap_or<T>(option: Option<T>, default: T) -> T {
      match option {
      None => default,
      Some(value) => value,
      }
      }
      ```

      The trick here is that the default value must have the same type as the value
      that might be inside the `Option<T>`. Using it is dead simple in our case:

      ```rust
      # fn find(haystack: &str, needle: char) -> Option<usize> {
      # for (offset, c) in haystack.char_indices() {
      # if c == needle {
      # return Some(offset);
      # }
      # }
      # None
      # }
      #
      # fn extension(file_name: &str) -> Option<&str> {
      # find(file_name, '.').map(|i| &file_name[i+1..])
      # }
      fn main() {
      assert_eq!(extension("foobar.csv").unwrap_or("rs"), "csv");
      assert_eq!(extension("foobar").unwrap_or("rs"), "rs");
      }
      ```

      (Note that `unwrap_or` is [defined as a method][3] on `Option<T>` in the
      standard library, so we use that here instead of the free-standing function we
      defined above. Don't forget to check out the more general [`unwrap_or_else`][4]
      method.)

      There is one more combinator that we think is worth paying special attention to:
      `and_then`. It makes it easy to compose distinct computations that admit the
      *possibility of absence*. For example, much of the code in this section is
      about finding an extension given a file name. In order to do this, you first
      need the file name which is typically extracted from a file *path*. While most
      file paths have a file name, not *all* of them do. For example, `.`, `..` or
      `/`.

      So, we are tasked with the challenge of finding an extension given a file
      *path*. Let's start with explicit case analysis:

      ```rust
      # fn extension(file_name: &str) -> Option<&str> { None }
      fn file_path_ext_explicit(file_path: &str) -> Option<&str> {
      match file_name(file_path) {
      None => None,
      Some(name) => match extension(name) {
      None => None,
      Some(ext) => Some(ext),
      }
      }
      }

      fn file_name(file_path: &str) -> Option<&str> {
      // implementation elided
      unimplemented!()
      }
      ```

      You might think that we could just use the `map` combinator to reduce the case
      analysis, but its type doesn't quite fit. Namely, `map` takes a function that
      does something only with the inner value. The result of that function is then
      *always* [rewrapped with `Some`](#code-option-map). Instead, we need something
      like `map`, but which allows the caller to return another `Option`. Its generic
      implementation is even simpler than `map`:

      ```rust
      fn and_then<F, T, A>(option: Option<T>, f: F) -> Option<A>
      where F: FnOnce(T) -> Option<A> {
      match option {
      None => None,
      Some(value) => f(value),
      }
      }
      ```

      Now we can rewrite our `file_path_ext` function without explicit case analysis:

      ```rust
      # fn extension(file_name: &str) -> Option<&str> { None }
      # fn file_name(file_path: &str) -> Option<&str> { None }
      fn file_path_ext(file_path: &str) -> Option<&str> {
      file_name(file_path).and_then(extension)
      }
      ```

      The `Option` type has many other combinators [defined in the standard
      library][5]. It is a good idea to skim this list and familiarize
      yourself with what's available—they can often reduce case analysis
      for you. Familiarizing yourself with these combinators will pay
      dividends because many of them are also defined (with similar
      semantics) for `Result`, which we will talk about next.

      Combinators make using types like `Option` ergonomic because they reduce
      explicit case analysis. They are also composable because they permit the caller
      to handle the possibility of absence in their own way. Methods like `unwrap`
      remove choices because they will panic if `Option<T>` is `None`.

      ## The `Result` type형식

      The `Result` type is also
      [defined in the standard library][6]:

      ```rust
      enum Result<T, E> {
      Ok(T),
      Err(E),
      }
      ```

      The `Result` type is a richer version of `Option`. Instead of expressing the
      possibility of *absence* like `Option` does, `Result` expresses the possibility
      of *error*. Usually, the *error* is used to explain why the result of some
      computation failed. This is a strictly more general form of `Option`. Consider
      the following type alias, which is semantically equivalent to the real
      `Option<T>` in every way:

      ```rust
      type Option<T> = Result<T, ()>;
      ```

      This fixes the second type parameter of `Result` to always be `()` (pronounced
      “unit” or “empty tuple”). Exactly one value inhabits the `()` type: `()`. (Yup,
      the type and value level terms have the same notation!)

      The `Result` type is a way of representing one of two possible outcomes in a
      computation. By convention, one outcome is meant to be expected or “`Ok`” while
      the other outcome is meant to be unexpected or “`Err`”.

      Just like `Option`, the `Result` type also has an
      [`unwrap` method
      defined][7]
      in the standard library. Let's define it:

      ```rust
      # enum Result<T, E> { Ok(T), Err(E) }
      impl<T, E: ::std::fmt::Debug> Result<T, E> {
      fn unwrap(self) -> T {
      match self {
      Result::Ok(val) => val,
      Result::Err(err) =>
      panic!("called `Result::unwrap()` on an `Err` value: {:?}", err),
      }
      }
      }
      ```

      This is effectively the same as our [definition for
      `Option::unwrap`](#code-option-def-unwrap), except it includes the
      error value in the `panic!` message. This makes debugging easier, but
      it also requires us to add a [`Debug`][8] constraint on the `E` type
      parameter (which represents our error type). Since the vast majority
      of types should satisfy the `Debug` constraint, this tends to work out
      in practice. (`Debug` on a type simply means that there's a reasonable
      way to print a human readable description of values with that type.)

      OK, let's move on to an example.

      ### Parsing integers변수 파싱

      The Rust standard library makes converting strings to integers dead simple.
      It's so easy in fact, that it is very tempting to write something like the
      following:

      ```rust
      fn double_number(number_str: &str) -> i32 {
      2 * number_str.parse::<i32>().unwrap()
      }

      fn main() {
      let n: i32 = double_number("10");
      assert_eq!(n, 20);
      }
      ```

      At this point, you should be skeptical of calling `unwrap`. For example, if
      the string doesn't parse as a number, you'll get a panic:

      ```text
      thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }', /home/rustbuild/src/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libcore/result.rs:729
      ```

      This is rather unsightly, and if this happened inside a library you're
      using, you might be understandably annoyed. Instead, we should try to
      handle the error in our function and let the caller decide what to
      do. This means changing the return type of `double_number`. But to
      what? Well, that requires looking at the signature of the [`parse`
      method][9] in the standard library:

      ```rust,ignore
      impl str {
      fn parse<F: FromStr>(&self) -> Result<F, F::Err>;
      }
      ```

      Hmm. So we at least know that we need to use a `Result`. Certainly, it's
      possible that this could have returned an `Option`. After all, a string either
      parses as a number or it doesn't, right? That's certainly a reasonable way to
      go, but the implementation internally distinguishes *why* the string didn't
      parse as an integer. (Whether it's an empty string, an invalid digit, too big
      or too small.) Therefore, using a `Result` makes sense because we want to
      provide more information than simply “absence.” We want to say *why* the
      parsing failed. You should try to emulate this line of reasoning when faced
      with a choice between `Option` and `Result`. If you can provide detailed error
      information, then you probably should. (We'll see more on this later.)

      OK, but how do we write our return type? The `parse` method as defined
      above is generic over all the different number types defined in the
      standard library. We could (and probably should) also make our
      function generic, but let's favor explicitness for the moment. We only
      care about `i32`, so we need to [find its implementation of
      `FromStr`](../std/primitive.i32.html) (do a `CTRL-F` in your browser
      for “FromStr”) and look at its [associated type][10] `Err`. We did
      this so we can find the concrete error type. In this case, it's
      [`std::num::ParseIntError`](../std/num/struct.ParseIntError.html).
      Finally, we can rewrite our function:

      ```rust
      use std::num::ParseIntError;

      fn double_number(number_str: &str) -> Result<i32, ParseIntError> {
      match number_str.parse::<i32>() {
      Ok(n) => Ok(2 * n),
      Err(err) => Err(err),
      }
      }

      fn main() {
      match double_number("10") {
      Ok(n) => assert_eq!(n, 20),
      Err(err) => println!("Error: {:?}", err),
      }
      }
      ```

      This is a little better, but now we've written a lot more code! The case
      analysis has once again bitten us.

      Combinators to the rescue! Just like `Option`, `Result` has lots of combinators
      defined as methods. There is a large intersection of common combinators between
      `Result` and `Option`. In particular, `map` is part of that intersection:

      ```rust
      use std::num::ParseIntError;

      fn double_number(number_str: &str) -> Result<i32, ParseIntError> {
      number_str.parse::<i32>().map(|n| 2 * n)
      }

      fn main() {
      match double_number("10") {
      Ok(n) => assert_eq!(n, 20),
      Err(err) => println!("Error: {:?}", err),
      }
      }
      ```

      The usual suspects are all there for `Result`, including
      [`unwrap_or`](../std/result/enum.Result.html#method.unwrap_or) and
      [`and_then`](../std/result/enum.Result.html#method.and_then).
      Additionally, since `Result` has a second type parameter, there are
      combinators that affect only the error type, such as
      [`map_err`](../std/result/enum.Result.html#method.map_err) (instead of
      `map`) and [`or_else`](../std/result/enum.Result.html#method.or_else)
      (instead of `and_then`).

      ### The `Result` type alias idiom형식의 다른 표현법

      In the standard library, you may frequently see types like
      `Result<i32>`. But wait, [we defined `Result`](#code-result-def-1) to
      have two type parameters. How can we get away with only specifying
      one? The key is to define a `Result` type alias that *fixes* one of
      the type parameters to a particular type. Usually the fixed type is
      the error type. For example, our previous example parsing integers
      could be rewritten like this:

      ```rust
      use std::num::ParseIntError;
      use std::result;

      type Result<T> = result::Result<T, ParseIntError>;

      fn double_number(number_str: &str) -> Result<i32> {
      unimplemented!();
      }
      ```

      Why would we do this? Well, if we have a lot of functions that could return
      `ParseIntError`, then it's much more convenient to define an alias that always
      uses `ParseIntError` so that we don't have to write it out all the time.

      The most prominent place this idiom is used in the standard library is
      with [`io::Result`](../std/io/type.Result.html). Typically, one writes
      `io::Result<T>`, which makes it clear that you're using the `io`
      module's type alias instead of the plain definition from
      `std::result`. (This idiom is also used for
      [`fmt::Result`](../std/fmt/type.Result.html).)

      ## A brief interlude: unwrapping isn't evil

      If you've been following along, you might have noticed that I've taken a pretty
      hard line against calling methods like `unwrap` that could `panic` and abort
      your program. *Generally speaking*, this is good advice.

      However, `unwrap` can still be used judiciously. What exactly justifies use of
      `unwrap` is somewhat of a grey area and reasonable people can disagree. I'll
      summarize some of my *opinions* on the matter.

      * **In examples and quick 'n' dirty code.** Sometimes you're writing examples
      or a quick program, and error handling simply isn't important. Beating the
      convenience of `unwrap` can be hard in such scenarios, so it is very
      appealing.
      * **When panicking indicates a bug in the program.** When the invariants of
      your code should prevent a certain case from happening (like, say, popping
      from an empty stack), then panicking can be permissible. This is because it
      exposes a bug in your program. This can be explicit, like from an `assert!`
      failing, or it could be because your index into an array was out of bounds.

      This is probably not an exhaustive list. Moreover, when using an
      `Option`, it is often better to use its
      [`expect`](../std/option/enum.Option.html#method.expect)
      method. `expect` does exactly the same thing as `unwrap`, except it
      prints a message you give to `expect`. This makes the resulting panic
      a bit nicer to deal with, since it will show your message instead of
      “called unwrap on a `None` value.”

      My advice boils down to this: use good judgment. There's a reason why the words
      “never do X” or “Y is considered harmful” don't appear in my writing. There are
      trade offs to all things, and it is up to you as the programmer to determine
      what is acceptable for your use cases. My goal is only to help you evaluate
      trade offs as accurately as possible.

      Now that we've covered the basics of error handling in Rust, and
      explained unwrapping, let's start exploring more of the standard
      library.

      # Working with multiple error types

      Thus far, we've looked at error handling where everything was either an
      `Option<T>` or a `Result<T, SomeError>`. But what happens when you have both an
      `Option` and a `Result`? Or what if you have a `Result<T, Error1>` and a
      `Result<T, Error2>`? Handling *composition of distinct error types* is the next
      challenge in front of us, and it will be the major theme throughout the rest of
      this chapter.

      ## Composing `Option` and `Result`

      So far, I've talked about combinators defined for `Option` and combinators
      defined for `Result`. We can use these combinators to compose results of
      different computations without doing explicit case analysis.

      Of course, in real code, things aren't always as clean. Sometimes you have a
      mix of `Option` and `Result` types. Must we resort to explicit case analysis,
      or can we continue using combinators?

      For now, let's revisit one of the first examples in this chapter:

      ```rust,should_panic
      use std::env;

      fn main() {
      let mut argv = env::args();
      let arg: String = argv.nth(1).unwrap(); // error 1
      let n: i32 = arg.parse().unwrap(); // error 2
      println!("{}", 2 * n);
      }
      ```

      Given our new found knowledge of `Option`, `Result` and their various
      combinators, we should try to rewrite this so that errors are handled properly
      and the program doesn't panic if there's an error.

      The tricky aspect here is that `argv.nth(1)` produces an `Option` while
      `arg.parse()` produces a `Result`. These aren't directly composable. When faced
      with both an `Option` and a `Result`, the solution is *usually* to convert the
      `Option` to a `Result`. In our case, the absence of a command line parameter
      (from `env::args()`) means the user didn't invoke the program correctly. We
      could just use a `String` to describe the error. Let's try:

      ```rust
      use std::env;

      fn double_arg(mut argv: env::Args) -> Result<i32, String> {
      argv.nth(1)
      .ok_or("Please give at least one argument".to_owned())
      .and_then(|arg| arg.parse::<i32>().map_err(|err| err.to_string()))
      }

      fn main() {
      match double_arg(env::args()) {
      Ok(n) => println!("{}", n),
      Err(err) => println!("Error: {}", err),
      }
      }
      ```

      There are a couple new things in this example. The first is the use of the
      [`Option::ok_or`](../std/option/enum.Option.html#method.ok_or)
      combinator. This is one way to convert an `Option` into a `Result`. The
      conversion requires you to specify what error to use if `Option` is `None`.
      Like the other combinators we've seen, its definition is very simple:

      ```rust
      fn ok_or<T, E>(option: Option<T>, err: E) -> Result<T, E> {
      match option {
      Some(val) => Ok(val),
      None => Err(err),
      }
      }
      ```

      The other new combinator used here is
      [`Result::map_err`](../std/result/enum.Result.html#method.map_err).
      This is just like `Result::map`, except it maps a function on to the *error*
      portion of a `Result` value. If the `Result` is an `Ok(...)` value, then it is
      returned unmodified.

      We use `map_err` here because it is necessary for the error types to remain
      the same (because of our use of `and_then`). Since we chose to convert the
      `Option<String>` (from `argv.nth(1)`) to a `Result<String, String>`, we must
      also convert the `ParseIntError` from `arg.parse()` to a `String`.

      ## The limits of combinators

      Doing IO and parsing input is a very common task, and it's one that I
      personally have done a lot of in Rust. Therefore, we will use (and continue to
      use) IO and various parsing routines to exemplify error handling.

      Let's start simple. We are tasked with opening a file, reading all of its
      contents and converting its contents to a number. Then we multiply it by `2`
      and print the output.

      Although I've tried to convince you not to use `unwrap`, it can be useful
      to first write your code using `unwrap`. It allows you to focus on your problem
      instead of the error handling, and it exposes the points where proper error
      handling need to occur. Let's start there so we can get a handle on the code,
      and then refactor it to use better error handling.

      ```rust,should_panic
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> i32 {
      let mut file = File::open(file_path).unwrap(); // error 1
      let mut contents = String::new();
      file.read_to_string(&mut contents).unwrap(); // error 2
      let n: i32 = contents.trim().parse().unwrap(); // error 3
      2 * n
      }

      fn main() {
      let doubled = file_double("foobar");
      println!("{}", doubled);
      }
      ```

      (N.B. The `AsRef<Path>` is used because those are the
      [same bounds used on
      `std::fs::File::open`](../std/fs/struct.File.html#method.open).
      This makes it ergnomic to use any kind of string as a file path.)

      There are three different errors that can occur here:

      1. A problem opening the file.
      2. A problem reading data from the file.
      3. A problem parsing the data as a number.

      The first two problems are described via the
      [`std::io::Error`](../std/io/struct.Error.html) type. We know this
      because of the return types of
      [`std::fs::File::open`](../std/fs/struct.File.html#method.open) and
      [`std::io::Read::read_to_string`](../std/io/trait.Read.html#method.read_to_string).
      (Note that they both use the [`Result` type alias
      idiom](#the-result-type-alias-idiom) described previously. If you
      click on the `Result` type, you'll [see the type
      alias](../std/io/type.Result.html), and consequently, the underlying
      `io::Error` type.) The third problem is described by the
      [`std::num::ParseIntError`](../std/num/struct.ParseIntError.html)
      type. The `io::Error` type in particular is *pervasive* throughout the
      standard library. You will see it again and again.

      Let's start the process of refactoring the `file_double` function. To make this
      function composable with other components of the program, it should *not* panic
      if any of the above error conditions are met. Effectively, this means that the
      function should *return an error* if any of its operations fail. Our problem is
      that the return type of `file_double` is `i32`, which does not give us any
      useful way of reporting an error. Thus, we must start by changing the return
      type from `i32` to something else.

      The first thing we need to decide: should we use `Option` or `Result`? We
      certainly could use `Option` very easily. If any of the three errors occur, we
      could simply return `None`. This will work *and it is better than panicking*,
      but we can do a lot better. Instead, we should pass some detail about the error
      that occurred. Since we want to express the *possibility of error*, we should
      use `Result<i32, E>`. But what should `E` be? Since two *different* types of
      errors can occur, we need to convert them to a common type. One such type is
      `String`. Let's see how that impacts our code:

      ```rust
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, String> {
      File::open(file_path)
      .map_err(|err| err.to_string())
      .and_then(|mut file| {
      let mut contents = String::new();
      file.read_to_string(&mut contents)
      .map_err(|err| err.to_string())
      .map(|_| contents)
      })
      .and_then(|contents| {
      contents.trim().parse::<i32>()
      .map_err(|err| err.to_string())
      })
      .map(|n| 2 * n)
      }

      fn main() {
      match file_double("foobar") {
      Ok(n) => println!("{}", n),
      Err(err) => println!("Error: {}", err),
      }
      }
      ```

      This code looks a bit hairy. It can take quite a bit of practice before code
      like this becomes easy to write. The way we write it is by *following the
      types*. As soon as we changed the return type of `file_double` to
      `Result<i32, String>`, we had to start looking for the right combinators. In
      this case, we only used three different combinators: `and_then`, `map` and
      `map_err`.

      `and_then` is used to chain multiple computations where each computation could
      return an error. After opening the file, there are two more computations that
      could fail: reading from the file and parsing the contents as a number.
      Correspondingly, there are two calls to `and_then`.

      `map` is used to apply a function to the `Ok(...)` value of a `Result`. For
      example, the very last call to `map` multiplies the `Ok(...)` value (which is
      an `i32`) by `2`. If an error had occurred before that point, this operation
      would have been skipped because of how `map` is defined.

      `map_err` is the trick the makes all of this work. `map_err` is just like
      `map`, except it applies a function to the `Err(...)` value of a `Result`. In
      this case, we want to convert all of our errors to one type: `String`. Since
      both `io::Error` and `num::ParseIntError` implement `ToString`, we can call the
      `to_string()` method to convert them.

      With all of that said, the code is still hairy. Mastering use of combinators is
      important, but they have their limits. Let's try a different approach: early
      returns.

      ## Early returns

      I'd like to take the code from the previous section and rewrite it using *early
      returns*. Early returns let you exit the function early. We can't return early
      in `file_double` from inside another closure, so we'll need to revert back to
      explicit case analysis.

      ```rust
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, String> {
      let mut file = match File::open(file_path) {
      Ok(file) => file,
      Err(err) => return Err(err.to_string()),
      };
      let mut contents = String::new();
      if let Err(err) = file.read_to_string(&mut contents) {
      return Err(err.to_string());
      }
      let n: i32 = match contents.trim().parse() {
      Ok(n) => n,
      Err(err) => return Err(err.to_string()),
      };
      Ok(2 * n)
      }

      fn main() {
      match file_double("foobar") {
      Ok(n) => println!("{}", n),
      Err(err) => println!("Error: {}", err),
      }
      }
      ```

      Reasonable people can disagree over whether this code is better that the code
      that uses combinators, but if you aren't familiar with the combinator approach,
      this code looks simpler to read to me. It uses explicit case analysis with
      `match` and `if let`. If an error occurs, it simply stops executing the
      function and returns the error (by converting it to a string).

      Isn't this a step backwards though? Previously, we said that the key to
      ergonomic error handling is reducing explicit case analysis, yet we've reverted
      back to explicit case analysis here. It turns out, there are *multiple* ways to
      reduce explicit case analysis. Combinators aren't the only way.

      ## The `try!` macro

      A cornerstone of error handling in Rust is the `try!` macro. The `try!` macro
      abstracts case analysis just like combinators, but unlike combinators, it also
      abstracts *control flow*. Namely, it can abstract the *early return* pattern
      seen above.

      Here is a simplified definition of a `try!` macro:

      ```rust
      macro_rules! try {
      ($e:expr) => (match $e {
      Ok(val) => val,
      Err(err) => return Err(err),
      });
      }
      ```

      (The [real definition](../std/macro.try!.html) is a bit more
      sophisticated. We will address that later.)

      Using the `try!` macro makes it very easy to simplify our last example. Since
      it does the case analysis and the early return for us, we get tighter code that
      is easier to read:

      ```rust
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, String> {
      let mut file = try!(File::open(file_path).map_err(|e| e.to_string()));
      let mut contents = String::new();
      try!(file.read_to_string(&mut contents).map_err(|e| e.to_string()));
      let n = try!(contents.trim().parse::<i32>().map_err(|e| e.to_string()));
      Ok(2 * n)
      }

      fn main() {
      match file_double("foobar") {
      Ok(n) => println!("{}", n),
      Err(err) => println!("Error: {}", err),
      }
      }
      ```

      The `map_err` calls are still necessary given
      [our definition of `try!`](#code-try-def-simple).
      This is because the error types still need to be converted to `String`.
      The good news is that we will soon learn how to remove those `map_err` calls!
      The bad news is that we will need to learn a bit more about a couple important
      traits in the standard library before we can remove the `map_err` calls.

      ## Defining your own error type

      Before we dive into some of the standard library error traits, I'd like to wrap
      up this section by removing the use of `String` as our error type in the
      previous examples.

      Using `String` as we did in our previous examples is convenient because it's
      easy to convert errors to strings, or even make up your own errors as strings
      on the spot. However, using `String` for your errors has some downsides.

      The first downside is that the error messages tend to clutter your
      code. It's possible to define the error messages elsewhere, but unless
      you're unusually disciplined, it is very tempting to embed the error
      message into your code. Indeed, we did exactly this in a [previous
      example](#code-error-double-string).

      The second and more important downside is that `String`s are *lossy*. That is,
      if all errors are converted to strings, then the errors we pass to the caller
      become completely opaque. The only reasonable thing the caller can do with a
      `String` error is show it to the user. Certainly, inspecting the string to
      determine the type of error is not robust. (Admittedly, this downside is far
      more important inside of a library as opposed to, say, an application.)

      For example, the `io::Error` type embeds an
      [`io::ErrorKind`](../std/io/enum.ErrorKind.html),
      which is *structured data* that represents what went wrong during an IO
      operation. This is important because you might want to react differently
      depending on the error. (e.g., A `BrokenPipe` error might mean quitting your
      program gracefully while a `NotFound` error might mean exiting with an error
      code and showing an error to the user.) With `io::ErrorKind`, the caller can
      examine the type of an error with case analysis, which is strictly superior
      to trying to tease out the details of an error inside of a `String`.

      Instead of using a `String` as an error type in our previous example of reading
      an integer from a file, we can define our own error type that represents errors
      with *structured data*. We endeavor to not drop information from underlying
      errors in case the caller wants to inspect the details.

      The ideal way to represent *one of many possibilities* is to define our own
      sum type using `enum`. In our case, an error is either an `io::Error` or a
      `num::ParseIntError`, so a natural definition arises:

      ```rust
      use std::io;
      use std::num;

      // We derive `Debug` because all types should probably derive `Debug`.
      // This gives us a reasonable human readable description of `CliError` values.
      #[derive(Debug)]
      enum CliError {
      Io(io::Error),
      Parse(num::ParseIntError),
      }
      ```

      Tweaking our code is very easy. Instead of converting errors to strings, we
      simply convert them to our `CliError` type using the corresponding value
      constructor:

      ```rust
      # #[derive(Debug)]
      # enum CliError { Io(::std::io::Error), Parse(::std::num::ParseIntError) }
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, CliError> {
      let mut file = try!(File::open(file_path).map_err(CliError::Io));
      let mut contents = String::new();
      try!(file.read_to_string(&mut contents).map_err(CliError::Io));
      let n: i32 = try!(contents.trim().parse().map_err(CliError::Parse));
      Ok(2 * n)
      }

      fn main() {
      match file_double("foobar") {
      Ok(n) => println!("{}", n),
      Err(err) => println!("Error: {:?}", err),
      }
      }
      ```

      The only change here is switching `map_err(|e| e.to_string())` (which converts
      errors to strings) to `map_err(CliError::Io)` or `map_err(CliError::Parse)`.
      The *caller* gets to decide the level of detail to report to the user. In
      effect, using a `String` as an error type removes choices from the caller while
      using a custom `enum` error type like `CliError` gives the caller all of the
      conveniences as before in addition to *structured data* describing the error.

      A rule of thumb is to define your own error type, but a `String` error type
      will do in a pinch, particularly if you're writing an application. If you're
      writing a library, defining your own error type should be strongly preferred so
      that you don't remove choices from the caller unnecessarily.

      # Standard library traits used for error handling

      The standard library defines two integral traits for error handling:
      [`std::error::Error`](../std/error/trait.Error.html) and
      [`std::convert::From`](../std/convert/trait.From.html). While `Error`
      is designed specifically for generically describing errors, the `From`
      trait serves a more general role for converting values between two
      distinct types.

      ## The `Error` trait

      The `Error` trait is [defined in the standard
      library](../std/error/trait.Error.html):

      ```rust
      use std::fmt::{Debug, Display};

      trait Error: Debug + Display {
      /// A short description of the error.
      fn description(&self) -> &str;

      /// The lower level cause of this error, if any.
      fn cause(&self) -> Option<&Error> { None }
      }
      ```

      This trait is super generic because it is meant to be implemented for *all*
      types that represent errors. This will prove useful for writing composable code
      as we'll see later. Otherwise, the trait allows you to do at least the
      following things:

      * Obtain a `Debug` representation of the error.
      * Obtain a user-facing `Display` representation of the error.
      * Obtain a short description of the error (via the `description` method).
      * Inspect the causal chain of an error, if one exists (via the `cause` method).

      The first two are a result of `Error` requiring impls for both `Debug` and
      `Display`. The latter two are from the two methods defined on `Error`. The
      power of `Error` comes from the fact that all error types impl `Error`, which
      means errors can be existentially quantified as a
      [trait object](../book/trait-objects.html).
      This manifests as either `Box<Error>` or `&Error`. Indeed, the `cause` method
      returns an `&Error`, which is itself a trait object. We'll revisit the
      `Error` trait's utility as a trait object later.

      For now, it suffices to show an example implementing the `Error` trait. Let's
      use the error type we defined in the
      [previous section](#defining-your-own-error-type):

      ```rust
      use std::io;
      use std::num;

      // We derive `Debug` because all types should probably derive `Debug`.
      // This gives us a reasonable human readable description of `CliError` values.
      #[derive(Debug)]
      enum CliError {
      Io(io::Error),
      Parse(num::ParseIntError),
      }
      ```

      This particular error type represents the possibility of two types of errors
      occurring: an error dealing with I/O or an error converting a string to a
      number. The error could represent as many error types as you want by adding new
      variants to the `enum` definition.

      Implementing `Error` is pretty straight-forward. It's mostly going to be a lot
      explicit case analysis.

      ```rust,ignore
      use std::error;
      use std::fmt;

      impl fmt::Display for CliError {
      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
      match *self {
      // Both underlying errors already impl `Display`, so we defer to
      // their implementations.
      CliError::Io(ref err) => write!(f, "IO error: {}", err),
      CliError::Parse(ref err) => write!(f, "Parse error: {}", err),
      }
      }
      }

      impl error::Error for CliError {
      fn description(&self) -> &str {
      // Both underlying errors already impl `Error`, so we defer to their
      // implementations.
      match *self {
      CliError::Io(ref err) => err.description(),
      // Normally we can just write `err.description()`, but the error
      // type has a concrete method called `description`, which conflicts
      // with the trait method. For now, we must explicitly call
      // `description` through the `Error` trait.
      CliError::Parse(ref err) => error::Error::description(err),
      }
      }

      fn cause(&self) -> Option<&error::Error> {
      match *self {
      // N.B. Both of these implicitly cast `err` from their concrete
      // types (either `&io::Error` or `&num::ParseIntError`)
      // to a trait object `&Error`. This works because both error types
      // implement `Error`.
      CliError::Io(ref err) => Some(err),
      CliError::Parse(ref err) => Some(err),
      }
      }
      }
      ```

      We note that this is a very typical implementation of `Error`: match on your
      different error types and satisfy the contracts defined for `description` and
      `cause`.

      ## The `From` trait

      The `std::convert::From` trait is
      [defined in the standard
      library](../std/convert/trait.From.html):

      ```rust
      trait From<T> {
      fn from(T) -> Self;
      }
      ```

      Deliciously simple, yes? `From` is very useful because it gives us a generic
      way to talk about conversion *from* a particular type `T` to some other type
      (in this case, “some other type” is the subject of the impl, or `Self`).
      The crux of `From` is the
      [set of implementations provided by the standard
      library](../std/convert/trait.From.html).

      Here are a few simple examples demonstrating how `From` works:

      ```rust
      let string: String = From::from("foo");
      let bytes: Vec<u8> = From::from("foo");
      let cow: ::std::borrow::Cow<str> = From::from("foo");
      ```

      OK, so `From` is useful for converting between strings. But what about errors?
      It turns out, there is one critical impl:

      ```rust,ignore
      impl<'a, E: Error + 'a> From<E> for Box<Error + 'a>
      ```

      This impl says that for *any* type that impls `Error`, we can convert it to a
      trait object `Box<Error>`. This may not seem terribly surprising, but it is
      useful in a generic context.

      Remember the two errors we were dealing with previously? Specifically,
      `io::Error` and `num::ParseIntError`. Since both impl `Error`, they work with
      `From`:

      ```rust
      use std::error::Error;
      use std::fs;
      use std::io;
      use std::num;

      // We have to jump through some hoops to actually get error values.
      let io_err: io::Error = io::Error::last_os_error();
      let parse_err: num::ParseIntError = "not a number".parse::<i32>().unwrap_err();

      // OK, here are the conversions.
      let err1: Box<Error> = From::from(io_err);
      let err2: Box<Error> = From::from(parse_err);
      ```

      There is a really important pattern to recognize here. Both `err1` and `err2`
      have the *same type*. This is because they are existentially quantified types,
      or trait objects. In particularly, their underlying type is *erased* from the
      compiler's knowledge, so it truly sees `err1` and `err2` as exactly the same.
      Additionally, we constructed `err1` and `err2` using precisely the same
      function call: `From::from`. This is because `From::from` is overloaded on both
      its argument and its return type.

      This pattern is important because it solves a problem we had earlier: it gives
      us a way to reliably convert errors to the same type using the same function.

      Time to revisit an old friend; the `try!` macro.

      ## The real `try!` macro

      Previously, we presented this definition of `try!`:

      ```rust
      macro_rules! try {
      ($e:expr) => (match $e {
      Ok(val) => val,
      Err(err) => return Err(err),
      });
      }
      ```

      This is not it's real definition. It's real definition is
      [in the standard library](../std/macro.try!.html):

      ```rust
      macro_rules! try {
      ($e:expr) => (match $e {
      Ok(val) => val,
      Err(err) => return Err(::std::convert::From::from(err)),
      });
      }
      ```

      There's one tiny but powerful change: the error value is passed through
      `From::from`. This makes the `try!` macro a lot more powerful because it gives
      you automatic type conversion for free.

      Armed with our more powerful `try!` macro, let's take a look at code we wrote
      previously to read a file and convert its contents to an integer:

      ```rust
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, String> {
      let mut file = try!(File::open(file_path).map_err(|e| e.to_string()));
      let mut contents = String::new();
      try!(file.read_to_string(&mut contents).map_err(|e| e.to_string()));
      let n = try!(contents.trim().parse::<i32>().map_err(|e| e.to_string()));
      Ok(2 * n)
      }
      ```

      Earlier, we promised that we could get rid of the `map_err` calls. Indeed, all
      we have to do is pick a type that `From` works with. As we saw in the previous
      section, `From` has an impl that let's it convert any error type into a
      `Box<Error>`:

      ```rust
      use std::error::Error;
      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, Box<Error>> {
      let mut file = try!(File::open(file_path));
      let mut contents = String::new();
      try!(file.read_to_string(&mut contents));
      let n = try!(contents.trim().parse::<i32>());
      Ok(2 * n)
      }
      ```

      We are getting very close to ideal error handling. Our code has very little
      overhead as a result from error handling because the `try!` macro encapsulates
      three things simultaneously:

      1. Case analysis.
      2. Control flow.
      3. Error type conversion.

      When all three things are combined, we get code that is unencumbered by
      combinators, calls to `unwrap` or case analysis.

      There's one little nit left: the `Box<Error>` type is *opaque*. If we
      return a `Box<Error>` to the caller, the caller can't (easily) inspect
      underlying error type. The situation is certainly better than `String`
      because the caller can call methods like
      [`description`](../std/error/trait.Error.html#tymethod.description)
      and [`cause`](../std/error/trait.Error.html#method.cause), but the
      limitation remains: `Box<Error>` is opaque. (N.B. This isn't entirely
      true because Rust does have runtime reflection, which is useful in
      some scenarios that are [beyond the scope of this
      chapter](https://crates.io/crates/error).)

      It's time to revisit our custom `CliError` type and tie everything together.

      ## Composing custom error types

      In the last section, we looked at the real `try!` macro and how it does
      automatic type conversion for us by calling `From::from` on the error value.
      In particular, we converted errors to `Box<Error>`, which works, but the type
      is opaque to callers.

      To fix this, we use the same remedy that we're already familiar with: a custom
      error type. Once again, here is the code that reads the contents of a file and
      converts it to an integer:

      ```rust
      use std::fs::File;
      use std::io::{self, Read};
      use std::num;
      use std::path::Path;

      // We derive `Debug` because all types should probably derive `Debug`.
      // This gives us a reasonable human readable description of `CliError` values.
      #[derive(Debug)]
      enum CliError {
      Io(io::Error),
      Parse(num::ParseIntError),
      }

      fn file_double_verbose<P: AsRef<Path>>(file_path: P) -> Result<i32, CliError> {
      let mut file = try!(File::open(file_path).map_err(CliError::Io));
      let mut contents = String::new();
      try!(file.read_to_string(&mut contents).map_err(CliError::Io));
      let n: i32 = try!(contents.trim().parse().map_err(CliError::Parse));
      Ok(2 * n)
      }
      ```

      Notice that we still have the calls to `map_err`. Why? Well, recall the
      definitions of [`try!`](#code-try-def) and [`From`](#code-from-def). The
      problem is that there is no `From` impl that allows us to convert from error
      types like `io::Error` and `num::ParseIntError` to our own custom `CliError`.
      Of course, it is easy to fix this! Since we defined `CliError`, we can impl
      `From` with it:

      ```rust
      # #[derive(Debug)]
      # enum CliError { Io(io::Error), Parse(num::ParseIntError) }
      use std::io;
      use std::num;

      impl From<io::Error> for CliError {
      fn from(err: io::Error) -> CliError {
      CliError::Io(err)
      }
      }

      impl From<num::ParseIntError> for CliError {
      fn from(err: num::ParseIntError) -> CliError {
      CliError::Parse(err)
      }
      }
      ```

      All these impls are doing is teaching `From` how to create a `CliError` from
      other error types. In our case, construction is as simple as invoking the
      corresponding value constructor. Indeed, it is *typically* this easy.

      We can finally rewrite `file_double`:

      ```rust
      # use std::io;
      # use std::num;
      # enum CliError { Io(::std::io::Error), Parse(::std::num::ParseIntError) }
      # impl From<io::Error> for CliError {
      # fn from(err: io::Error) -> CliError { CliError::Io(err) }
      # }
      # impl From<num::ParseIntError> for CliError {
      # fn from(err: num::ParseIntError) -> CliError { CliError::Parse(err) }
      # }

      use std::fs::File;
      use std::io::Read;
      use std::path::Path;

      fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, CliError> {
      let mut file = try!(File::open(file_path));
      let mut contents = String::new();
      try!(file.read_to_string(&mut contents));
      let n: i32 = try!(contents.trim().parse());
      Ok(2 * n)
      }
      ```

      The only thing we did here was remove the calls to `map_err`. They are no
      longer needed because the `try!` macro invokes `From::from` on the error value.
      This works because we've provided `From` impls for all the error types that
      could appear.

      If we modified our `file_double` function to perform some other operation, say,
      convert a string to a float, then we'd need to add a new variant to our error
      type:

      ```rust
      use std::io;
      use std::num;

      enum CliError {
      Io(io::Error),
      ParseInt(num::ParseIntError),
      ParseFloat(num::ParseFloatError),
      }
      ```

      And add a new `From` impl:

      ```rust
      # enum CliError {
      # Io(::std::io::Error),
      # ParseInt(num::ParseIntError),
      # ParseFloat(num::ParseFloatError),
      # }

      use std::num;

      impl From<num::ParseFloatError> for CliError {
      fn from(err: num::ParseFloatError) -> CliError {
      CliError::ParseFloat(err)
      }
      }
      ```

      And that's it!

      ## Advice for library writers

      If your library needs to report custom errors, then you should
      probably define your own error type. It's up to you whether or not to
      expose its representation (like
      [`ErrorKind`](../std/io/enum.ErrorKind.html)) or keep it hidden (like
      [`ParseIntError`](../std/num/struct.ParseIntError.html)). Regardless
      of how you do it, it's usually good practice to at least provide some
      information about the error beyond just its `String`
      representation. But certainly, this will vary depending on use cases.

      At a minimum, you should probably implement the
      [`Error`](../std/error/trait.Error.html)
      trait. This will give users of your library some minimum flexibility for
      [composing errors](#the-real-try-macro). Implementing the `Error` trait also
      means that users are guaranteed the ability to obtain a string representation
      of an error (because it requires impls for both `fmt::Debug` and
      `fmt::Display`).

      Beyond that, it can also be useful to provide implementations of `From` on your
      error types. This allows you (the library author) and your users to
      [compose more detailed errors](#composing-custom-error-types). For example,
      [`csv::Error`](http://burntsushi.net/rustdoc/csv/enum.Error.html)
      provides `From` impls for both `io::Error` and `byteorder::Error`.

      Finally, depending on your tastes, you may also want to define a
      [`Result` type alias](#the-result-type-alias-idiom), particularly if your
      library defines a single error type. This is used in the standard library
      for [`io::Result`](../std/io/type.Result.html)
      and [`fmt::Result`](../std/fmt/type.Result.html).

      # Case study: A program to read population data

      This chapter was long, and depending on your background, it might be
      rather dense. While there is plenty of example code to go along with
      the prose, most of it was specifically designed to be pedagogical. So,
      we're going to do something new: a case study.

      For this, we're going to build up a command line program that lets you
      query world population data. The objective is simple: you give it a location
      and it will tell you the population. Despite the simplicity, there is a lot
      that can go wrong!

      The data we'll be using comes from the [Data Science
      Toolkit][11]. I've prepared some data from it for this exercise. You
      can either grab the [world population data][12] (41MB gzip compressed,
      145MB uncompressed) or just the [US population data][13] (2.2MB gzip
      compressed, 7.2MB uncompressed).

      Up until now, we've kept the code limited to Rust's standard library. For a real
      task like this though, we'll want to at least use something to parse CSV data,
      parse the program arguments and decode that stuff into Rust types automatically. For that, we'll use the
      [`csv`](https://crates.io/crates/csv),
      and [`rustc-serialize`](https://crates.io/crates/rustc-serialize) crates.

      ## Initial setup

      We're not going to spend a lot of time on setting up a project with
      Cargo because it is already covered well in [the Cargo
      chapter](../book/hello-cargo) and [Cargo's documentation][14].

      To get started from scratch, run `cargo new --bin city-pop` and make sure your
      `Cargo.toml` looks something like this:

      ```text
      [package]
      name = "city-pop"
      version = "0.1.0"
      authors = ["Andrew Gallant <jamslam@gmail.com>"]

      [[bin]]
      name = "city-pop"

      [dependencies]
      csv = "0.*"
      rustc-serialize = "0.*"
      getopts = "0.*"
      ```

      You should already be able to run:

      ```text
      cargo build --release
      ./target/release/city-pop
      # Outputs: Hello, world!
      ```

      ## Argument parsing

      Let's get argument parsing out of the way. we won't go into too much
      detail on Getopts, but there is [some good documentation][15]
      describing it. The short story is that Getopts generates an argument
      parser and a help message from a vector of options (The fact that it
      is a vector is hidden behind a struct and a set of methods). Once the
      parsing is done, we can decode the program arguments into a Rust
      struct. From there, we can get information about the flags, for
      instance, wether they were passed in, and what arguments they
      had. Here's our program with the appropriate `extern crate`
      statements, and the basic argument setup for Getopts:

      ```rust,ignore
      extern crate getopts;
      extern crate rustc_serialize;

      use getopts::Options;
      use std::env;

      fn print_usage(program: &str, opts: Options) {
      println!("{}", opts.usage(&format!("Usage: {} [options] <data-path> <city>", program)));
      }

      fn main() {
      let args: Vec<String> = env::args().collect();
      let program = args[0].clone();

      let mut opts = Options::new();
      opts.optflag("h", "help", "Show this usage message.");

      let matches = match opts.parse(&args[1..]) {
      Ok(m) => { m }
      Err(e) => { panic!(e.to_string()) }
      };
      if matches.opt_present("h") {
      print_usage(&program, opts);
      return;
      }
      let data_path = args[1].clone();
      let city = args[2].clone();

      // Do stuff with information
      }
      ```

      First, we get a vector of the arguments passed into our program. We
      then store the first one, knowing that it is our program's name. Once
      that's done, we set up our argument flags, in this case a simplistic
      help message flag. Once we have the argument flags set up, we use
      `Options.parse` to parse the argument vector (starting from index one,
      becouse index 0 is the program name). If this was successful, we
      assign matches to the parsed object, if not, we panic. Once past that,
      we test if the user passed in the help flag, and if so print the usage
      message. The option help messages are constructed by Getopts, so all
      we have to do to print the usage message is tell it what we want it to
      print for the program name and template. If the user has not passed in
      the help flag, we assign the proper variables to their corresponding
      arguments.

      ## Writing the logic

      We're all different in how we write code, but error handling is
      usually the last thing we want to think about. This isn't very good
      practice for good design, but it can be useful for rapidly
      prototyping. In our case, because Rust forces us to be explicit about
      error handling, it will also make it obvious what parts of our program
      can cause errors. Why? Because Rust will make us call `unwrap`! This
      can give us a nice bird's eye view of how we need to approach error
      handling.

      In this case study, the logic is really simple. All we need to do is parse the
      CSV data given to us and print out a field in matching rows. Let's do it. (Make
      sure to add `extern crate csv;` to the top of your file.)

      ```rust,ignore
      // This struct represents the data in each row of the CSV file.
      // Type based decoding absolves us of a lot of the nitty gritty error
      // handling, like parsing strings as integers or floats.
      #[derive(Debug, RustcDecodable)]
      struct Row {
      country: String,
      city: String,
      accent_city: String,
      region: String,

      // Not every row has data for the population, latitude or longitude!
      // So we express them as `Option` types, which admits the possibility of
      // absence. The CSV parser will fill in the correct value for us.
      population: Option<u64>,
      latitude: Option<f64>,
      longitude: Option<f64>,
      }

      fn print_usage(program: &str, opts: Options) {
      println!("{}", opts.usage(&format!("Usage: {} [options] <data-path> <city>", program)));
      }

      fn main() {
      let args: Vec<String> = env::args().collect();
      let program = args[0].clone();

      let mut opts = Options::new();
      opts.optflag("h", "help", "Show this usage message.");

      let matches = match opts.parse(&args[1..]) {
      Ok(m) => { m }
      Err(e) => { panic!(e.to_string()) }
      };

      if matches.opt_present("h") {
      print_usage(&program, opts);
      return;
      }

      let data_file = args[1].clone();
      let data_path = Path::new(&data_file);
      let city = args[2].clone();

      let file = fs::File::open(data_path).unwrap();
      let mut rdr = csv::Reader::from_reader(file);

      for row in rdr.decode::<Row>() {
      let row = row.unwrap();

      if row.city == city {
      println!("{}, {}: {:?}",
      row.city, row.country,
      row.population.expect("population count"));
      }
      }
      }
      ```

      Let's outline the errors. We can start with the obvious: the three places that
      `unwrap` is called:

      1. [`fs::File::open`](../std/fs/struct.File.html#method.open)
      can return an
      [`io::Error`](../std/io/struct.Error.html).
      2. [`csv::Reader::decode`](http://burntsushi.net/rustdoc/csv/struct.Reader.html#method.decode)
      decodes one record at a time, and
      [decoding a
      record](http://burntsushi.net/rustdoc/csv/struct.DecodedRecords.html)
      (look at the `Item` associated type on the `Iterator` impl)
      can produce a
      [`csv::Error`](http://burntsushi.net/rustdoc/csv/enum.Error.html).
      3. If `row.population` is `None`, then calling `expect` will panic.

      Are there any others? What if we can't find a matching city? Tools like `grep`
      will return an error code, so we probably should too. So we have logic errors
      specific to our problem, IO errors and CSV parsing errors. We're going to
      explore two different ways to approach handling these errors.

      I'd like to start with `Box<Error>`. Later, we'll see how defining our own
      error type can be useful.

      ## Error handling with `Box<Error>`

      `Box<Error>` is nice because it *just works*. You don't need to define your own
      error types and you don't need any `From` implementations. The downside is that
      since `Box<Error>` is a trait object, it *erases the type*, which means the
      compiler can no longer reason about its underlying type.

      [Previously](#the-limits-of-combinators) we started refactoring our code by
      changing the type of our function from `T` to `Result<T, OurErrorType>`. In
      this case, `OurErrorType` is just `Box<Error>`. But what's `T`? And can we add
      a return type to `main`?

      The answer to the second question is no, we can't. That means we'll need to
      write a new function. But what is `T`? The simplest thing we can do is to
      return a list of matching `Row` values as a `Vec<Row>`. (Better code would
      return an iterator, but that is left as an exercise to the reader.)

      Let's refactor our code into its own function, but keep the calls to `unwrap`.
      Note that we opt to handle the possibility of a missing population count by
      simply ignoring that row.

      ```rust,ignore
      struct Row {
      // unchanged
      }

      struct PopulationCount {
      city: String,
      country: String,
      // This is no longer an `Option` because values of this type are only
      // constructed if they have a population count.
      count: u64,
      }

      fn print_usage(program: &str, opts: Options) {
      println!("{}", opts.usage(&format!("Usage: {} [options] <data-path> <city>", program)));
      }

      fn search<P: AsRef<Path>>(file_path: P, city: &str) -> Vec<PopulationCount> {
      let mut found = vec![];
      let file = fs::File::open(file_path).unwrap();
      let mut rdr = csv::Reader::from_reader(file);
      for row in rdr.decode::<Row>() {
      let row = row.unwrap();
      match row.population {
      None => { } // skip it
      Some(count) => if row.city == city {
      found.push(PopulationCount {
      city: row.city,
      country: row.country,
      count: count,
      });
      },
      }
      }
      found
      }

      fn main() {
      let args: Vec<String> = env::args().collect();
      let program = args[0].clone();

      let mut opts = Options::new();
      opts.optflag("h", "help", "Show this usage message.");

      let matches = match opts.parse(&args[1..]) {
      Ok(m) => { m }
      Err(e) => { panic!(e.to_string()) }
      };
      if matches.opt_present("h") {
      print_usage(&program, opts);
      return;
      }

      let data_file = args[1].clone();
      let data_path = Path::new(&data_file);
      let city = args[2].clone();
      for pop in search(&data_path, &city) {
      println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
      }
      }

      ```

      While we got rid of one use of `expect` (which is a nicer variant of `unwrap`),
      we still should handle the absence of any search results.

      To convert this to proper error handling, we need to do the following:

      1. Change the return type of `search` to be `Result<Vec<PopulationCount>,
      Box<Error>>`.
      2. Use the [`try!` macro](#code-try-def) so that errors are returned to the
      caller instead of panicking the program.
      3. Handle the error in `main`.

      Let's try it:

      ```rust,ignore
      fn search<P: AsRef<Path>>
      (file_path: P, city: &str)
      -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
      let mut found = vec![];
      let file = try!(fs::File::open(file_path));
      let mut rdr = csv::Reader::from_reader(file);
      for row in rdr.decode::<Row>() {
      let row = try!(row);
      match row.population {
      None => { } // skip it
      Some(count) => if row.city == city {
      found.push(PopulationCount {
      city: row.city,
      country: row.country,
      count: count,
      });
      },
      }
      }
      if found.is_empty() {
      Err(From::from("No matching cities with a population were found."))
      } else {
      Ok(found)
      }
      }
      ```

      Instead of `x.unwrap()`, we now have `try!(x)`. Since our function returns a
      `Result<T, E>`, the `try!` macro will return early from the function if an
      error occurs.

      There is one big gotcha in this code: we used `Box<Error + Send + Sync>`
      instead of `Box<Error>`. We did this so we could convert a plain string to an
      error type. We need these extra bounds so that we can use the
      [corresponding `From`
      impls](../std/convert/trait.From.html):

      ```rust,ignore
      // We are making use of this impl in the code above, since we call `From::from`
      // on a `&'static str`.
      impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a>

      // But this is also useful when you need to allocate a new string for an
      // error message, usually with `format!`.
      impl From<String> for Box<Error + Send + Sync>
      ```

      Now that we've seen how to do proper error handling with `Box<Error>`, let's
      try a different approach with our own custom error type. But first, let's take
      a quick break from error handling and add support for reading from `stdin`.

      ## Reading from stdin

      In our program, we accept a single file for input and do one pass over the
      data. This means we probably should be able to accept input on stdin. But maybe
      we like the current format too—so let's have both!

      Adding support for stdin is actually quite easy. There are only two things we
      have to do:

      1. Tweak the program arguments so that a single parameter—the
      city—can be accepted while the population data is read from stdin.
      2. Modify the program so that an option `-f` can take the file, if it
      is not passed into stdin.
      3. Modify the `search` function to take an *optional* file path. When `None`,
      it should know to read from stdin.

      First, here's the new usage:

      ```rust,ignore
      fn print_usage(program: &str, opts: Options) {
      println!("{}", opts.usage(&format!("Usage: {} [options] <city>", program)));
      }
      ```
      The next part is going to be only a little harder:

      ```rust,ignore
      ...
      let mut opts = Options::new();
      opts.optopt("f", "file", "Choose an input file, instead of using STDIN.", "NAME");
      opts.optflag("h", "help", "Show this usage message.");
      ...
      let file = matches.opt_str("f");
      let data_file = file.as_ref().map(Path::new);

      let city = if !matches.free.is_empty() {
      matches.free[0].clone()
      } else {
      print_usage(&program, opts);
      return;
      };

      for pop in search(&data_file, &city) {
      println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
      }
      ...
      ```

      In this peice of code, we take `file` (which has the type
      `Option<String>`), and convert it to a type that `search` can use, in
      this case, `&Option<AsRef<Path>>`. Do do this, we take a reference of
      file, and map `Path::new` onto it. In this case, `as_ref()` converts
      the `Option<String>` into an `Option<&str>`, and from there, we can
      execute `Path::new` to the content of the optional, and return the
      optional of the new value. Once we have that, it is a simple matter of
      getting the `city` argument and executing `search`.

      Modifying `search` is slightly trickier. The `csv` crate can build a
      parser out of
      [any type that implements `io::Read`](http://burntsushi.net/rustdoc/csv/struct.Reader.html#method.from_reader).
      But how can we use the same code over both types? There's actually a
      couple ways we could go about this. One way is to write `search` such
      that it is generic on some type parameter `R` that satisfies
      `io::Read`. Another way is to just use trait objects:

      ```rust,ignore
      fn search<P: AsRef<Path>>
      (file_path: &Option<P>, city: &str)
      -> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
      let mut found = vec![];
      let input: Box<io::Read> = match *file_path {
      None => Box::new(io::stdin()),
      Some(ref file_path) => Box::new(try!(fs::File::open(file_path))),
      };
      let mut rdr = csv::Reader::from_reader(input);
      // The rest remains unchanged!
      }
      ```

      ## Error handling with a custom type

      Previously, we learned how to
      [compose errors using a custom error type](#composing-custom-error-types).
      We did this by defining our error type as an `enum` and implementing `Error`
      and `From`.

      Since we have three distinct errors (IO, CSV parsing and not found), let's
      define an `enum` with three variants:

      ```rust,ignore
      #[derive(Debug)]
      enum CliError {
      Io(io::Error),
      Csv(csv::Error),
      NotFound,
      }
      ```

      And now for impls on `Display` and `Error`:

      ```rust,ignore
      impl fmt::Display for CliError {
      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
      match *self {
      CliError::Io(ref err) => err.fmt(f),
      CliError::Csv(ref err) => err.fmt(f),
      CliError::NotFound => write!(f, "No matching cities with a \
      population were found."),
      }
      }
      }

      impl Error for CliError {
      fn description(&self) -> &str {
      match *self {
      CliError::Io(ref err) => err.description(),
      CliError::Csv(ref err) => err.description(),
      CliError::NotFound => "not found",
      }
      }
      }
      ```

      Before we can use our `CliError` type in our `search` function, we need to
      provide a couple `From` impls. How do we know which impls to provide? Well,
      we'll need to convert from both `io::Error` and `csv::Error` to `CliError`.
      Those are the only external errors, so we'll only need two `From` impls for
      now:

      ```rust,ignore
      impl From<io::Error> for CliError {
      fn from(err: io::Error) -> CliError {
      CliError::Io(err)
      }
      }

      impl From<csv::Error> for CliError {
      fn from(err: csv::Error) -> CliError {
      CliError::Csv(err)
      }
      }
      ```

      The `From` impls are important because of how
      [`try!` is defined](#code-try-def). In particular, if an error occurs,
      `From::from` is called on the error, which in this case, will convert it to our
      own error type `CliError`.

      With the `From` impls done, we only need to make two small tweaks to our
      `search` function: the return type and the “not found” error. Here it is in
      full:

      ```rust,ignore
      fn search<P: AsRef<Path>>
      (file_path: &Option<P>, city: &str)
      -> Result<Vec<PopulationCount>, CliError> {
      let mut found = vec![];
      let input: Box<io::Read> = match *file_path {
      None => Box::new(io::stdin()),
      Some(ref file_path) => Box::new(try!(fs::File::open(file_path))),
      };
      let mut rdr = csv::Reader::from_reader(input);
      for row in rdr.decode::<Row>() {
      let row = try!(row);
      match row.population {
      None => { } // skip it
      Some(count) => if row.city == city {
      found.push(PopulationCount {
      city: row.city,
      country: row.country,
      count: count,
      });
      },
      }
      }
      if found.is_empty() {
      Err(CliError::NotFound)
      } else {
      Ok(found)
      }
      }
      ```

      No other changes are necessary.

      ## Adding functionality

      Writing generic code is great, because generalizing stuff is cool, and
      it can then be useful later. But sometimes, the juice isn't worth the
      squeeze. Look at what we just did in the previous step:

      1. Defined a new error type.
      2. Added impls for `Error`, `Display` and two for `From`.

      The big downside here is that our program didn't improve a whole lot.
      There is quite a bit of overhead to representing errors with `enum`s,
      especially in short programs like this.

      *One* useful aspect of using a custom error type like we've done here is that
      the `main` function can now choose to handle errors differently. Previously,
      with `Box<Error>`, it didn't have much of a choice: just print the message.
      We're still doing that here, but what if we wanted to, say, add a `--quiet`
      flag? The `--quiet` flag should silence any verbose output.

      Right now, if the program doesn't find a match, it will output a message saying
      so. This can be a little clumsy, especially if you intend for the program to
      be used in shell scripts.

      So let's start by adding the flags. Like before, we need to tweak the usage
      string and add a flag to the Option variable. Once were done that, Getopts does the rest:

      ```rust,ignore
      ...
      let mut opts = Options::new();
      opts.optopt("f", "file", "Choose an input file, instead of using STDIN.", "NAME");
      opts.optflag("h", "help", "Show this usage message.");
      opts.optflag("q", "quit", "Silences errors and warnings.");
      ...
      ```

      Now we just need to implement our “quiet” functionality. This requires us to
      tweak the case analysis in `main`:

      ```rust,ignore
      match search(&args.arg_data_path, &args.arg_city) {
      Err(CliError::NotFound) if args.flag_quiet => process::exit(1),
      Err(err) => fatal!("{}", err),
      Ok(pops) => for pop in pops {
      println!("{}, {}: {:?}", pop.city, pop.country, pop.count);
      }
      }
      ```

      Certainly, we don't want to be quiet if there was an IO error or if the data
      failed to parse. Therefore, we use case analysis to check if the error type is
      `NotFound` *and* if `--quiet` has been enabled. If the search failed, we still
      quit with an exit code (following `grep`'s convention).

      If we had stuck with `Box<Error>`, then it would be pretty tricky to implement
      the `--quiet` functionality.

      This pretty much sums up our case study. From here, you should be ready to go
      out into the world and write your own programs and libraries with proper error
      handling.

      # The Short Story

      Since this chapter is long, it is useful to have a quick summary for error
      handling in Rust. These are some good “rules of thumb." They are emphatically
      *not* commandments. There are probably good reasons to break every one of these
      heuristics!

      * If you're writing short example code that would be overburdened by error
      handling, it's probably just fine to use `unwrap` (whether that's
      [`Result::unwrap`](../std/result/enum.Result.html#method.unwrap),
      [`Option::unwrap`](../std/option/enum.Option.html#method.unwrap)
      or preferably
      [`Option::expect`](../std/option/enum.Option.html#method.expect)).
      Consumers of your code should know to use proper error handling. (If they
      don't, send them here!)
      * If you're writing a quick 'n' dirty program, don't feel ashamed if you use
      `unwrap`. Be warned: if it winds up in someone else's hands, don't be
      surprised if they are agitated by poor error messages!
      * If you're writing a quick 'n' dirty program and feel ashamed about panicking
      anyway, then using either a `String` or a `Box<Error + Send + Sync>` for your
      error type (the `Box<Error + Send + Sync>` type is because of the
      [available `From` impls](../std/convert/trait.From.html)).
      * Otherwise, in a program, define your own error types with appropriate
      [`From`](../std/convert/trait.From.html)
      and
      [`Error`](../std/error/trait.Error.html)
      impls to make the [`try!`](../std/macro.try!.html)
      macro more ergnomic.
      * If you're writing a library and your code can produce errors, define your own
      error type and implement the
      [`std::error::Error`](../std/error/trait.Error.html)
      trait. Where appropriate, implement
      [`From`](../std/convert/trait.From.html) to make both
      your library code and the caller's code easier to write. (Because of Rust's
      coherence rules, callers will not be able to impl `From` on your error type,
      so your library should do it.)
      * Learn the combinators defined on
      [`Option`](../std/option/enum.Option.html)
      and
      [`Result`](../std/result/enum.Result.html).
      Using them exclusively can be a bit tiring at times, but I've personally
      found a healthy mix of `try!` and combinators to be quite appealing.
      `and_then`, `map` and `unwrap_or` are my favorites.

      [1]: ../book/patterns.html
      [2]: ../std/option/enum.Option.html#method.map
      [3]: ../std/option/enum.Option.html#method.unwrap_or
      [4]: ../std/option/enum.Option.html#method.unwrap_or_else
      [5]: ../std/option/enum.Option.html
      [6]: ../std/result/
      [7]: ../std/result/enum.Result.html#method.unwrap
      [8]: ../std/fmt/trait.Debug.html
      [9]: ../std/primitive.str.html#method.parse
      [10]: ../book/associated-types.html
      [11]: https://github.com/petewarden/dstkdata
      [12]: http://burntsushi.net/stuff/worldcitiespop.csv.gz
      [13]: http://burntsushi.net/stuff/uscitiespop.csv.gz
      [14]: http://doc.crates.io/guide.html
      [15]: http://doc.rust-lang.org/getopts/getopts/index.html
      getting-started
      # 2. 시작하기(Getting Started) - 520%

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

      # Rust 설치하기

      첫 번째로 Rust를 사용하기 위해선 설치를 하여야합니다. 우선 우리가 Rust 를 다운로드 하기위해선 인터넷에 연결되어 있어야합니다.

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


      ## Platform support

      The Rust compiler runs on, and compiles to, a great number of platforms, though
      not all platforms are equally supported. Rust's support levels are organized
      into three tiers, each with a different set of guarantees.

      Platforms are identified by their "target triple" which is the string to inform
      the compiler what kind of output should be produced. The columns below indicate
      whether the corresponding component works on the specified platform.

      ### Tier 1

      Tier 1 platforms can be thought of as "guaranteed to build and work".
      Specifically they will each satisfy the following requirements:

      * Automated testing is set up to run tests for the platform.
      * Landing changes to the `rust-lang/rust` repository's master branch is gated on
      tests passing.
      * Official release artifacts are provided for the platform.
      * Documentation for how to use and how to build the platform is available.

      | Target | std |rustc|cargo| notes |
      |-------------------------------|-----|-----|-----|----------------------------|
      | `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

      Tier 2 platforms can be thought of as "guaranteed to build". Automated tests
      are not run so it's not guaranteed to produce a working build, but platforms
      often work to quite a good degree and patches are always welcome! Specifically,
      these platforms are required to have each of the following:

      * Automated building is set up, but may not be running tests.
      * Landing changes to the `rust-lang/rust` repository's master branch is gated on
      platforms **building**. Note that this means for some platforms only the
      standard library is compiled, but for others the full bootstrap is run.
      * Official release artifacts are provided for the platform.

      | Target | std |rustc|cargo| notes |
      |-------------------------------|-----|-----|-----|----------------------------|
      | `i686-pc-windows-msvc` | ✓ | ✓ | ✓ | 32-bit MSVC (Windows 7+) |

      ### Tier 3

      Tier 3 platforms are those which Rust has support for, but landing changes is
      not gated on the platform either building or passing tests. Working builds for
      these platforms may be spotty as their reliability is often defined in terms of
      community contributions. Additionally, release artifacts and installers are not
      provided, but there may be community infrastructure producing these in
      unofficial locations.

      | Target | std |rustc|cargo| notes
      플렛폼 지원


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


      ### 단계 1

      1단계 플렛폼들은 러스트 코드 빌드와 프로그램을 만들 수 있는 플렛폼입니다.

      요구사항 -
      - 플렛폼에서의 작동을 검증함.
      - `rustlang/rust` 레퍼토리의 master branch의 태스트를 통과함.
      - 플렛폼을 공식적으로 지원함.
      - 그 플렛폼에서 러스트를 빌드하고, 사용하는 문서가 작성되있음.


      | 타겟 플렛폼 | 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 |

      Note that this table can be expanded over time, this isn't the exhaustive set of
      tier 3 platforms that will ever be!

      ## Installing on Linux or Mac

      If we're on Linux or a Mac, all we need to do is open a terminal and type this:

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

      This will download a script, and stat the installation. If it all goes well,
      you’ll see this appear:
      이 표는 시간이 지남에 따라 계속 늘어날것이고, 이것들만이 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=<path> 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)
      ```

      From here, press `y` for ‘yes’, and then follow the rest of the prompts.

      ## Installing on Windows

      If you're on Windows, please download the appropriate [installer][install-page].

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

      ## Uninstalling

      Uninstalling Rust is as easy as installing it. On Linux or Mac, just run
      the uninstall script:

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

      If we used the Windows installer, we can re-run the `.msi` and it will give us
      an uninstall option.

      ## Troubleshooting

      If we've got Rust installed, we can open up a shell, and type this:

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

      You should see the version number, commit hash, and commit date.

      If you do, Rust has been installed successfully! Congrats!

      If you don't and you're on Windows, check that Rust is in your %PATH% system
      variable. If it isn't, run the installer again, select "Change" on the "Change,
      repair, or remove installation" page and ensure "Add to PATH" is installed on
      the local hard drive.

      If not, there are a number of places where we can get help. The easiest is
      [the #rust IRC channel on irc.mozilla.org][irc], which we can access through
      [Mibbit][mibbit]. Click that link, and we'll be chatting with other Rustaceans
      (a silly nickname we call ourselves) who can help us out. Other great resources
      include [the user’s forum][users], and [Stack Overflow][stackoverflow].

      [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

      This installer also installs a copy of the documentation locally, so we can
      read it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location.
      On Windows, it's in a `share/doc` directory, inside the directory to which Rust
      was installed.

      # Hello, world!

      Now that you have Rust installed, we'll help you write your first Rust program.
      It's traditional when learning a new language to write a little program to
      print the text “Hello, world!” to the screen, and in this section, we'll follow
      that tradition.

      The nice thing about starting with such a simple program is that you can
      quickly verify that your compiler is installed, and that it's working properly.
      Printing information to the screen is also just a pretty common thing to do, so
      practicing it early on is good.

      > Note: This book assumes basic familiarity with the command line. Rust itself
      > makes no specific demands about your editing, tooling, or where your code
      > lives, so if you prefer an IDE to the command line, that's an option. You may
      > want to check out [SolidOak], which was built specifically with Rust in mind.
      > There are a number of extensions in development by the community, and the
      > Rust team ships plugins for [various editors]. Configuring your editor or
      > IDE is out of the scope of this tutorial, so check the documentation for your
      > specific setup.

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

      ## Creating a Project File

      First, make a file to put your Rust code in. Rust doesn't care where your code
      lives, but for this book, I suggest making a *projects* directory in your home
      directory, and keeping all your projects there. Open a terminal and enter the
      following commands to make a directory for this particular project:

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

      > Note: If you’re on Windows and not using PowerShell, the `~` may not work.
      > Consult the documentation for your shell for more details.

      ## Writing and Running a Rust Program

      Next, make a new source file and call it *main.rs*. Rust files always end
      in a *.rs* extension. If you’re using more than one word in your filename, use
      an underscore to separate them; for example, you'd use *hello_world.rs* rather
      than *helloworld.rs*.

      Now open the *main.rs* file you just created, and type the following code:

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

      Save the file, and go back to your terminal window. On Linux or OSX, enter the
      following commands:

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

      In Windows, just replace `main` with `main.exe`. Regardless of your operating
      system, you should see the string `Hello, world!` print to the terminal. If you
      did, then congratulations! You've officially written a Rust program. That makes
      you a Rust programmer! Welcome.

      ## Anatomy of a Rust Program

      Now, let’s go over what just happened in your "Hello, world!" program in
      detail. Here's the first piece of the puzzle:
      여기서 `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% 변수안에 러스트 설치 경로가 들어있는지 확인하세요. 설치경로가 포함되있지 않으면, 러스트를 설치한 폴더의 경로를 추가 해주시길 바랍니다. _(어떻게 하는진 다들 아실거라 믿습니다)_

      불행하게도 윈도우 이외의 플렛폼에서 설치가 실패했다면, 도움을 받을 수 있는 곳이 있습니다. 가장 쉬운곳은 공식 [irc.mozilla.org의 #rust IRC 체널][irc] 입니다. IRC 클라이언트는 [Mibbit][mibbit] 을 사용하실수 있습니다. 다른 곳으론, [사용자 포럼][users]과 [(우리들의 친구) Stack Overflow][stackoverflow]가 있습니다.

      [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() {

      }
      ```

      These lines define a *function* in Rust. The `main` function is special: it's
      the beginning of every Rust program. The first line says, “I’m declaring a
      function named `main` that takes no arguments and returns nothing.” If there
      were arguments, they would go inside the parentheses (`(` and `)`), and because
      we aren’t returning anything from this function, we can omit the return type
      entirely.

      Also note that the function body is wrapped in curly braces (`{` and `}`). Rust
      requires these around all function bodies. It's considered good style to put
      the opening curly brace on the same line as the function declaration, with one
      space in between.

      Inside the `main()` function`main()` 함수 안에서:

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

      This line does all of the work in this little program: it prints text to the
      screen. There are a number of details that are important here. The first is
      that it’s indented with four spaces, not tabs.

      The second important part is the `println!()` line. This is calling a Rust
      *[macro]*, which is how metaprogramming is done in Rust. If it were calling a
      function instead, it would look like this: `println()` (without the !). We'll
      discuss Rust macros in more detail later, but for now you just need to
      know that when you see a `!` that means that you’re calling a macro instead of
      a normal function.


      [macro]: macros.html

      Next is `"Hello, world!"` which is a *string*. Strings are a surprisingly
      complicated topic in a systems programming language, and this is a *[statically
      allocated]* string. We pass this string as an argument to `println!`, which
      prints the string to the screen. Easy enough!

      [statically allocated]: the-stack-and-the-heap.html

      The line ends with a semicolon (`;`). Rust is an *[expression oriented]*
      language, which means that most things are expressions, rather than statements.
      The `;` indicates that this expression is over, and the next one is ready to
      begin. Most lines of Rust code end with a `;`.

      [expression-oriented language]: glossary.html#expression-oriented-language

      ## Compiling and Running Are Separate Steps컴파일과 실행은 다른 단계로 이루어짐

      In "Writing and Running a Rust Program", we showed you how to run a newly
      created program. We'll break that process down and examine each step now.

      Before running a Rust program, you have to compile it. You can use the Rust
      compiler by entering the `rustc` command and passing it the name of your source
      file, like this:

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

      If you come from a C or C++ background, you'll notice that this is similar to
      `gcc` or `clang`. After compiling successfully, Rust should output a binary
      executable, which you can see on Linux or OSX by entering the `ls` command in
      your shell as follows:

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

      On Windows, you'd enter:

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

      This shows we have two files: the source code, with an `.rs` extension, and the
      executable (`main.exe` on Windows, `main` everywhere else). All that's left to
      do from here is run the `main` or `main.exe` file, like this:

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

      If *main.rs* were your "Hello, world!" program, this would print `Hello,
      world!` to your terminal.

      If you come from a dynamic language like Ruby, Python, or JavaScript, you may
      not be used to compiling and running a program being separate steps. Rust is an
      *ahead-of-time compiled* language, which means that you can compile a program,
      give it to someone else, and they can run it even without Rust installed. If
      you give someone a `.rb` or `.py` or `.js` file, on the other hand, they need
      to have a Ruby, Python, or JavaScript implementation installed (respectively),
      but you only need one command to both compile and run your program. Everything
      is a tradeoff in language design.

      Just compiling with `rustc` is fine for simple programs, but as your project
      grows, you'll want to be able to manage all of the options your project has,
      and make it easy to share your code with other people and projects. Next, I'll
      introduce you to a tool called Cargo, which will help you write real-world Rust
      programs.

      # Hello, Cargo!

      Cargo is Rust’s build system and package manager, and Rustaceans use Cargo to
      manage their Rust projects. Cargo manages three things: building your code,
      downloading the libraries your code depends on, and building those libraries.
      We call libraries your code needs ‘dependencies’ since your code depends on
      them.

      The simplest Rust programs don’t have any dependencies, so right now, you'd
      only use the first part of its functionality. As you write more complex Rust
      programs, you’ll want to add dependencies, and if you start off using Cargo,
      that will be a lot easier to do.

      As the vast, vast majority of Rust projects use Cargo, we will assume that
      you’re using it for the rest of the book. Cargo comes installed with Rust
      itself, if you used the official installers. If you installed Rust through some
      other means, you can check if you have Cargo installed by typing:

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

      Into a terminal. If you see a version number, great! If you see an error like
      ‘`command not found`’, then you should look at the documentation for the system
      in which you installed Rust, to determine if Cargo is separate.

      ## Converting to Cargo

      Let’s convert the Hello World program to Cargo. To Cargo-fy a project, you need
      to do three things:

      1. Put your source file in the right directory.
      2. Get rid of the old executable (`main.exe` on Windows, `main` everywhere else)
      and make a new one.
      3. Make a Cargo configuration file.

      Let's get started!

      ### Creating a new Executable and Source Directory

      First, go back to your terminal, move to your *hello_world* directory, and
      enter the following commands:
      argo로 변환하기

      이제 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
      ```

      Cargo expects your source files to live inside a *src* directory, so do that
      first. This leaves the top-level project directory (in this case,
      *hello_world*) for READMEs, license information, and anything else not related
      to your code. In this way, using Cargo helps you keep your projects nice and
      tidy. There's a place for everything, and everything is in its place.

      Now, copy *main.rs* to the *src* directory, and delete the compiled file you
      created with `rustc`. As usual, replace `main` with `main.exe` if you're on
      Windows.

      This example retains `main.rs` as the source filename because it's creating an
      executable. If you wanted to make a library instead, you'd name the file
      `lib.rs`. This convention is used by Cargo to successfully compile your
      projects, but it can be overridden if you wish.

      ### Creating a Configuration File설정 파일 생성하기

      Next, create a new file inside your *hello_world* directory, and call it
      `Cargo.toml`.

      Make sure to capitalize the `C` in `Cargo.toml`, or Cargo won't know what to do
      with the configuration file.

      This file is in the *[TOML]* (Tom's Obvious, Minimal Language) format. TOML is
      similar to INI, but has some extra goodies, and is used as Cargo’s
      configuration format.

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

      Inside this file, type the following information: 이 파일을 대신해서, 다음의 것들을 입력 해주세요.

      ```toml
      [package]

      name = "hello_world"
      version = "0.0.1"
      authors = [ "Your name <you@example.com>" ]
      ```

      The first line, `[package]`, indicates that the following statements are
      configuring a package. As we add more information to this file, we’ll add other
      sections, but for now, we just have the package configuration.

      The other three lines set the three bits of configuration that Cargo needs to
      know to compile your program: its name, what version it is, and who wrote it.

      Once you've added this information to the *Cargo.toml* file, save it to finish
      creating the configuration file.

      ## Building and Running a Cargo Project Cargo프로젝트를 빌드하고 실행하기

      With your *Cargo.toml* file in place in your project's root directory, you
      should be ready to build and run your Hello World program! To do so, enter the
      following commands:

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

      Bam! If all goes well, `Hello, world!` should print to the terminal once more.

      You just built a project with `cargo build` and ran it with
      `./target/debug/hello_world`, but you can actually do both in one step with
      `cargo run` as follows:
      모두 잘 작동 하였으면, `Hello, world!`문자열이 당신의 터미널에 출력될것입니다.

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


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

      Notice that this example didn’t re-build the project. Cargo figured out that
      the file hasn’t changed, and so it just ran the binary. If you'd modified your
      source code, Cargo would have rebuilt the project before running it, and you
      would have seen something like this:

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

      Cargo checks to see if any of your project’s files have been modified, and only
      rebuilds your project if they’ve changed since the last time you built it
      Cargo는 자동으로 어느 프로젝트 파일이 수정되었는지 확인하고, 수정된 코드만 다시 빌드합니다.

      With simple projects, Cargo doesn't bring a whole lot over just using `rustc`,
      but it will become useful in future. With complex projects composed of multiple
      crates, it’s much easier to let Cargo coordinate the build. With Cargo, you can
      just run `cargo build`, and it should work the right way.

      ## Building for Release프로그램 릴리즈

      When your project is finally ready for release, you can use `cargo build
      --release` to compile your project with optimizations. These optimizations make
      your Rust code run faster, but turning them on makes your program take longer
      to compile. This is why there are two different profiles, one for development,
      and one for building the final program you’ll give to a user.

      Running this command also causes Cargo to create a new file called
      *Cargo.lock*, which looks like this:

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

      Cargo uses the *Cargo.lock* file to keep track of dependencies in your
      application. This is the Hello World project's *Cargo.lock* file. This project
      doesn't have dependencies, so the file is a bit sparse. Realistically, you
      won't ever need to touch this file yourself; just let Cargo handle it.

      That’s it! If you've been following along, you should have successfully built
      `hello_world` with Cargo.

      Even though the project is simple, it now uses much of the real tooling you’ll
      use for the rest of your Rust career. In fact, you can expect to start
      virtually all Rust projects with some variation on the following commands:

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

      ## Making A New Cargo Project the Easy Way

      You don’t have to go through that previous process every time you want to start
      a new project! Cargo can quickly make a bare-bones project directory that you
      can start developing in right away.

      To start a new project with Cargo, enter `cargo new` at the command line:
      무작정 따라하는 Cargo프로젝트 만들기

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

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


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

      This command passes `--bin` because the goal is to get straight to making an
      executable application, as opposed to a library. Executables are often called
      *binaries* (as in `/usr/bin`, if you’re on a Unix system).

      Cargo has generated two files and one directory for us: a `Cargo.toml` and a
      *src* directory with a *main.rs* file inside. These should look familliar,
      they’re exactly what we created by hand, above.

      This output is all you need to get started. First, open `Cargo.toml`. It should
      look something like this:

      ```toml
      [package]

      name = "hello_world"
      version = "0.1.0"
      authors = ["Your Name <you@example.com>"]
      ```

      Cargo has populated *Cargo.toml* with reasonable defaults based on the arguments
      you gave it and your `git` global configuration. You may notice that Cargo has
      also initialized the `hello_world` directory as a `git` repository.

      Here’s what should be in `src/main.rs``src/main.rs` 에는 다음의 코드가 작성되있을 것입니다:

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

      Cargo has generated a "Hello World!" for you, and you’re ready to start coding!

      > Note: If you want to look at Cargo in more detail, check out the official [Cargo
      guide], which covers all of its features.

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

      # Closing Thoughts

      This chapter covered the basics that will serve you well through the rest of
      this book, and the rest of your time with Rust. Now that you’ve got the tools
      down, we'll cover more about the Rust language itself.

      You have two options: Dive into a project with ‘[Learn Rust][learnrust]’, or
      start from the bottom and work your way up with ‘[Syntax and
      Semantics][syntax]’. More experienced systems programmers will probably prefer
      ‘Learn Rust’, while those from dynamic backgrounds may enjoy either. Different
      people learn differently! Choose whatever’s right for you
      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
      lifetimes
      # 5.9. 수명 (Lifetimes) - 9100%

      이 가이드는 러스트의 소유권 시스템을 설명하는 세 가이드 중 하나입니다. 이는 러스트의 가장 고유하면서 매력적인 동시에 러스트 개발자들이 반드시 친숙해져야 하는 특징입니다. 소유권을 통해 러스트는 스스로의 가장 거대한 목표인 메모리 안정성을 성취해냅니다. 관련된 몇가지 개념들이 있는데, 각각을 설명하는 장이 존재합니다. 다음과 같죠:

      * 핵심 개념인 [소유권][ownership]
      * [빌림][borrowing], 그리고 관련된 특징인 '참조'
      * 여러분이 지금 읽고 계시는 수명

      이 세 장들은 연관되어 있고, 순서대로 작성되어 있습니다. 소유권 시스템을 이해하기 위해선 세 장을 모두 필요로 할 것입니다.

      [ownership]: ownership.html
      [borrowing]: references-and-borrowing.html


      ## 개괄

      세부사항을 살펴보기 전에, 소유권 시스템에 관한 두 가지 중요한 점을 짚고 넘어가겠습니다.

      러스트는 안정성과 속도에 초점을 맞추고 있고, 이러한 목표들을 많은 '무비용 추상화 _zero-cost abstraction_'들을 통해 이루어냅니다. 다시 말해, 러스트에서 추상화는 그것이 작동하기 위해 필요한 최소한의 비용만을 필요로 합니다. 소유권 시스템은 무비용 추상화의 대표적인 예입니다. 이 가이드에서 이야기할 모든 분석들은 _컴파일 타임 내에 _이루어집니다. 이러한 기능들을 사용하기 위해 런타임에서 비용을 치를 필요는 없다는 이야기죠.

      하지만, 이 시스템 역시 치뤄야할 비용은 있기 마련인데, 바로 학습 곡선입니다. 러스트를 처음 접하는 많은 사용자들은 작성자는 아무 문제가 없다고 생각하는 프로그램을 러스트 컴파일러가 컴파일하기 거부하는 현상에 맞닥뜨립니다. 우리가 '소유권 검사기와의 싸움'이라고 부르는 현상이죠. 이는 보통 소유권이 어떻게 동작해야 하는 지에 대한 프로그래머의 생각과 실제 러스트가 구현하는 규칙들이 다르기 때문에 발생합니다. 이 글을 읽고 있는 당신도 처음엔 비슷한 경험을 할지 모릅니다. 좋은 소식은, 이러한 소유권 시스템 규칙들과 함께 작업을 하면 할수록 소유권 검사기와 싸울 일은 점점 적어진다고 다수의 숙련된 러스트 개발자들이 말한다는 거죠.

      그걸 명심하시고, 수명에 대해 배워봅시다.

      # 수명

      소유권자는 따로 있는 리소스에 대한 참조를 빌려주는 일은 꽤 복잡해질 수 있습니다. 예를 들어, 다음 일련의 명령을 생각해보세요.

      - 제가 어떤 리소스에 대한 제어권을 얻습니다.
      - 그리고 그 리소스에 대한 참조를 당신에게 빌려주는거죠.
      - 당신이 그 참조를 아직 들고 있는 시점에서, 제가 그 리소스로 할 일을 마쳤다고 판단하고, 해당 리소스의 할당을 해제합니다.
      - 그 후, 당신이 그 리소스를 사용하기로 마음먹습니다.

      아이구 이런! 당신의 참조는 이제 유효하지 않은 리소스를 가리키고 있습니다. 그 리소스가 메모리인 경우에, 이러한 현상은 댕글링 포인터(dangling pointer) 혹은 '해제 이후의 사용(use after free)'라고 불립니다.

      이걸 고치기 위해, 우리는 위의 예제에서 3번째 단계가 일어난 후에는 4번째 단계가 절대 일어나지 않을 것을 보장해 줄 필요가 있겠죠. Rust의 소유권 시스템은 수명(lifetime)이라는 개념을 통해 그 일을 해냅니다. 수명은 어떤 참조가 어떤 유효 범위(scope)안에서만 유효한지를 나타냅니다.

      참조를 인자로 받는 함수가 있을 때, 그 참조의 수명을 명시적으로, 혹은 암묵적으로 나타낼 수 있습니다.

      ```rust
      // implicit
      fn foo(x: &i32) {
      }

      // explicit
      fn bar<'a>(x: &'a i32) {
      }
      ```

      `'a`는 '수명 a'라고 읽습니다. 엄밀히 말하자면, 모든 참조는 자신과 관련된 수명을 가지고 있지만, 컴파일러가 있기 때문에 보통의 경우에는 당신이 그것을 굳이 언급하지 않아도 됩니다. 그 얘기를 좀 더 자세히 하기 전에, 일단 이 명시적 예제를 살펴보죠.

      ```rust,ignore
      fn bar&lt;'a>(...)
      ```

      We previously talked a little about [function syntax][functions], but we didn’t
      discuss the `<>`s after a function’s name. A function can have ‘generic
      parameters’ between the `<>`s, of which lifetimes are one kind. We’ll discuss
      other kinds of generics [later in the book][generics], but for now, let’s
      just focus on the lifetimes aspect
      이전에 간단히 [함수 문법][functions]에 대해 설명 했었는데, 하지만 함수이름 뒤의 `<>`에 대해서는 설명 하지 않았습니다. 함수의 '수명이 한 가지인 제널릭 인수'들을 `<>` 안에 선언 할 수 있습니다. 조금 뒤에서 다시 [여러가지 제널릭][generics]에 대해 설명하겠지만,
      지금으로썬 그저 수명의 사용에 대해 집중 하도록 합시다.

      [functions]: functions.html
      [generics]: generics.html

      수명을 선언하기 위해 `<>`를 이용합니다. `bar`라는 함수는 `'a`라고 불리는 하나의 수명을 가지고 있다고 말이죠. 만약 참조 매개변수가 두 개였다면, 아마 다음과 같았을 겁니다.

      ```rust,ignore
      fn bar<'a, 'b>(...)
      ```

      그 다음 우리의 매개변수 리스트에서, 우리가 명명한 수명들을 사용합니다.

      ```rust,ignore
      ...(x: &'a i32)
      ```

      만약 `&mut` 참조를 원했다면, 다음과 같았겠죠.

      ```rust,ignore
      ...(x: &'a mut i32)
      ```

      `&mut i32`와 `&'a mut i32`는 `&`와 `mut i32` 사이에 수명 `a`가 끼어들었다는 것을 제외하곤 동일합니다. 각각 `&mut i32`는 '`i32`로의 변경 가능한 참조', `&'a mut i32`는 '`'a'`의 수명을 갖는 `i32`로의 변경 가능한 참조' 라고 읽습니다.

      # In `struct`s

      [구조체(`struct`)][structs](`struct`)를 사용할 때에도 명시적 수명이 필요합니다.

      ```rust
      struct Foo<'a> {
      x: &'a i32,
      }

      fn main() {
      let y = &5; // this is the same as `let _y = 5; let y = &_y;`
      let f = Foo { x: y };

      println!("{}", f.x);
      }
      ```

      [structs]: structs.html

      위에서 볼 수 있듯, `struct` 역시 수명을 가질 수 있습니다. 함수와 비슷한 방식인데,

      ```rust
      struct Foo<'a> {
      # x: &'a i32,
      # }
      ```

      위와 같이 수명을 선언하고,

      ```rust
      # struct Foo<'a> {
      x: &'a i32,
      # }
      ```

      사용하는거죠. 여기서는 수명이 왜 필요한걸까요? `Foo`로의 참조가 그 안에 담겨있는 `i32`로의 참조보다 더 오래 살 수 없다는 것을 보장할 필요가 있기 때문입니다.

      ## `impl` blocks

      Let’s implement a method on `Foo`:

      ```rust
      struct Foo<'a> {
      x: &'a i32,
      }

      impl<'a> Foo<'a> {
      fn x(&self) -> &'a i32 { self.x }
      }

      fn main() {
      let y = &5; // this is the same as `let _y = 5; let y = &_y;`
      let f = Foo { x: y };

      println!("x is: {}", f.x());
      }
      ```

      As you can see, we need to declare a lifetime for `Foo` in the `impl` line. We repeat
      `'a` twice, just like on functions: `impl<'a>` defines a lifetime `'a`, and `Foo<'a>`
      uses it.

      ## Multiple lifetimes

      만약 참조가 여러개일때는, 다음과 같이 같은 수명을 주게 할 수 있습니다:

      ```rust
      fn x_or_y<'a>(x: &'a str, y: &'a str) -> &'a str {
      # x
      # }
      ```

      이것은 `x`와 `y`가 같은 범위 안에 살아있고, 반환값 또한 같은 범위 안에 살아있다는 것을 나타냅니다. 만약 `x`와 `y`가 다른 수명을 가지게 하고 싶다면, 다음과 같이 쓰면 됩니다:

      ```rust
      fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
      # x
      # }
      ```

      이 예시에서, `x`와 `y`는 서로 다른 유효 범위를 지니지만, 반환 값은 `x`와 같은 수명을 가지고 있습니다.

      ## 유효 범위에 대해 생각하기

      수명에 대해 좀 더 다뤄보기 위해 어떤 참조가 의미를 갖는(유효한) 유효 기간을 시각화해보죠. 다음과 같이요.

      ```rust
      fn main() {
      let y = &5; // -+ y goes into scope
      // |
      // stuff // |
      // |
      } // -+ y goes out of scope
      ```

      앞서 언급한 `Foo`를 집어넣어 볼까요?

      ```rust
      struct Foo<'a> {
      x: &'a i32,
      }

      fn main() {
      let y = &5; // -+ y goes into scope
      let f = Foo { x: y }; // -+ f goes into scope
      // stuff // |
      // |
      } // -+ f and y go out of scope
      ```

      `f`는 `y`의 유효 기간 내에서만 살아있고, 따라서 아무런 문제가 없습니다. 하지만 만약 그렇지 않다면 어떨까요? 다음의 코드는 제대로 작동하지 않습니다.

      ```rust,ignore
      struct Foo<'a> {
      x: &'a i32,
      }

      fn main() {
      let x; // -+ x goes into scope
      // |
      { // |
      let y = &5; // ---+ y goes into scope
      let f = Foo { x: y }; // ---+ f goes into scope
      x = &f.x; // | | error here
      } // ---+ f and y go out of scope
      // |
      println!("{}", x); // |
      } // -+ x goes out of scope
      ```

      이쿠! 보시다시피, `f`와 `y`의 유효 범위는 `x`의 그것보다 짧습니다. 그럼에도 불구하고 `x = &f.x`를 통해 `x`를 이제 곧 유효 범위를 나가는 녀석을 가리키는 참조로 만들었죠.

      명명된 수명(named lifetime)을 통해 유효 범위에게 이름을 줄 수 있습니다. 어떤 것에 대해 이야기하기 위해선 일단 이름부터 매겨야겠죠.

      ## 'static

      'static'이라는 이름의 수명은 특별한 녀석입니다. 어떤 녀석이 전체 프로그램에 해당하는 수명을 갖고 있음을 나타내죠. 많은 Rust 프로그래머들은 문자열을 다루면서 `'static`을 처음 마주하게 됩니다.

      ```rust
      let x: &'static str = "Hello, world.";
      ```

      문자열 리터럴은 `&'static str` 타입을 갖고 있는데, 이는 참조가 항상 살아 있는 상태이기 때문입니다. 이 리터럴들은 최종 바이너리의 데이터 영역에 들어가죠. 또 다른 예제는 전역 함수입니다.

      ```rust
      static FOO: i32 = 5;
      let x: &'static i32 = &FOO;
      ```

      위의 코드는 `i32`를 바이너리의 데이터 영역에 추가하고, `x`는 그에 대한 참조입니다.

      ## 수명의 생략(Lifetime Elision)

      Rust는 함수 몸체에서는 강력한 로컬 타입 추론을 제공하지만, 아이템 시그니처들에 대해 그 자신에 기반해 그 타입을 추론해내는 것은 금지되어 있습니다. 하지만, 사용자의 편의를 위해 '수명의 생략'이라 불리는, 아주 제한적인 차선의 추론 알고리즘이 함수 시그니처에서의 타입 추론에 적용됩니다. 이 때, 이 추론은 세 개의 쉽게 외울 수 있고 명백한 규칙을 기반으로 *수명 인자들만을* 추론해내며, 함수 몸체와는 무관하게 이루어집니다. 수명의 생략을 통해, 그와 관련된 실제 타입들에 대한 정보를 가리지 않으면서도 아이템 시그니처를 보다 간략하게 작성할 수 있습니다. 마치 로컬 타입 추론처럼요.

      수명의 생략에 대해 이야기 할 때, *입력 수명(input lifetime)*과 *출력 수명(output lifetime)*이라는 용어들이 사용됩니다. *입력 수명*이란 함수의 인자와 연관된 수명, *출력 수명*은 함수의 리턴 값과 연관된 수명을 의미합니다. 예를 들어, 다음 함수는 입력 수명을 가지고 있습니다.

      ```rust,ignore
      fn foo<'a>(bar: &'a str)
      ```

      이 녀석은 출력 수명을 가지고 있구요.

      ```rust,ignore
      fn foo<'a>() -> &'a str
      ```

      다음에 나올 함수는 두 수명을 모두 갖고 있네요.

      ```rust,ignore
      fn foo<'a>(bar: &'a str) -> &'a str
      ```

      앞서 언급한 세 가지 규칙은 다음과 같습니다.

      * 함수의 매개변수에서 생략된 수명들은 각각 별개의 수명 인자가 됩니다.

      * (생략되었건 아니건) 만약 정확히 한 개의 입력 수명만이 존재한다면, 그 수명이 해당 함수의 리턴 값들의 모든 생략된 수명에 할당됩니다.

      * 만약 다수의 입력 수명이 있지만 그 중 하나가 `&self`나 `&mut self`라면, `self`의 수명이 모든 생략된 출력 수명에 할당됩니다.

      위의 규칙들로 추론해 낼 수 없는 경우, 출력 수명의 생략은 에러를 발생시킵니다.

      ### 예제

      다음은 생략된 수명을 갖는 함수들의 예제들입니다. 각각의 수명이 생략된 형태의 함수들을 각각 수명이 생략되지 않고 확장된(expanded) 형태와 짝지어 놓았으니, 참고하세요.

      ```rust,ignore
      fn print(s: &str); // elided
      fn print<'a>(s: &'a str); // expanded

      fn debug(lvl: u32, s: &str); // elided
      fn debug<'a>(lvl: u32, s: &'a str); // expanded

      // In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
      // reference (`&`). Only things relating to references (such as a `struct`
      // which contains a reference) need lifetimes.

      fn substr(s: &str, until: u32) -> &str; // elided
      fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded

      fn get_str() -> &str; // ILLEGAL, no inputs

      fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
      fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is ambiguous

      fn get_mut(&mut self) -> &mut T; // elided
      fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded

      fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
      fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded

      fn new(buf: &mut [u8]) -> BufWriter; // elided
      fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
      mutability
      # 5.10. 가변성 (Mutability) - 99100%

      Rust에서, 변화할 수 있음을 나타내는 '가변성(Mutability)'은 다른 언어와는 약간 다르게 동작합니다. 가변성의 가장 중요한 측면은, 이것이 기본 상태가 아니라는 것입니다:

      ```rust,ignore
      let x = 5;
      x = 6; // error!
      ```

      (역자 주 : 다른 프로그래밍 언어와는 달리) 러스트에서는 아래와 같이 `mut` 키워드를 붙여야만 가변성을 부여할 수 있습니다:

      ```rust
      let mut x = 5;

      x = 6; // no problem!
      ```

      이것은 가변(mutable) [변수 바인딩(variable binding)][vb]입니다. 바인딩이 변경 가능하다는 것의 의미는, 바인딩이 어디를 가리키는지를 바꿀 수 있다는 얘기입니다. 따라서 위의 예제에서는, `x`에 있는 값이 변경된다기보다는, 바인딩이 어떤 `i32` 객체에서 다른 것으로 변화한다고 볼 수 있습니다.

      [vb]: variable-bindings.html

      만약 바인딩이 가리키는 곳의 내용을 바꾸기를 원한다면, [mutable reference][mr]를 사용해야 합니다:

      ```rust
      let mut x = 5;
      let y = &mut x;
      ```

      [mr]: references-and-borrowing.html

      `y`는 가변(mutable) 참조에 대한 불변(immutable) 바인딩이며, 이것은 (`y = &mut z`와 같이) `y`에 묶인 것을 또다른 무언가로 바꿔 묶을 수는 없지만, (`*y = 5`와 같이) `y`에 묶여있는 것 자체를 바꾸는 것은 가능합니다. 여기에는 아주 미묘한 차이가 있습니다.

      물론, 양쪽이 다 필요하다면 다음과 같이 할 수 있습니다.

      ```rust
      let mut x = 5;
      let mut y = &mut x;
      ```

      이제 `y`는 다른 값에 묶일 수 있고, 그것이 참조하는 값 자체도 바뀔 수 있습니다.

      `mut`는 [패턴][pattern]의 한 부분이라는 것에 주목하시길 바라며, 따라서 다음과 같이 할 수 있습니다:

      ```rust
      let (mut x, y) = (5, 6);

      fn foo(mut x: i32) {
      # }
      ```

      [pattern]: patterns.html

      # 내적(Interior) vs. 외적(Exterior) 가변성

      그러나, 러스트에서 무언가가 '불변(immutable)'이라고 말할 때, 이것이 변화가 불가능하다는 말은 아닙니다: 이것이 의미하는 바는, 어떤 무언가는 '외적 가변성(exterior mutability)'을 가질 수 있다는 뜻입니다. [`Arc`][arc] 와 관련하여 다음 예제에 대해 생각해 봅시다:

      ```rust
      use std::sync::Arc;

      let x = Arc::new(5);
      let y = x.clone();
      ```

      [arc]: ../std/sync/struct.Arc.html

      우리가 `clone()`을 호출할 때, `Arc`는 참조 카운트를 갱신합니다. 그러나 우리는 여기에 어떤 `mut`도 사용하지 않았기에, `x`는 불변(immutable) 바인딩이며, `&mut 5` 혹은 그 어떤 것도 취하지 않았습니다. 그럼 이것은 어떻게 된 일일까요?

      이것을 이해하기 위해서는 러스트의 기본 철학의 핵심인 메모리 안전성과, 그것이 돌아가는 방식인 [소유권][ownership] 시스템, 그리고 더 정확하게는 [빌림(borrowing)][borrowing]에 대해 다시 돌아볼 필요가 있습니다:

      > 어떤 리소스에 대해 다음 두 종류의 빌림 중 어느 쪽이든 가질 수 있지만, 두 종류의 빌림을 동시에 유지할 수는 없다:
      >
      > * 한 리소스로의 0개에서 N개까지의 참조(&T)
      > * 한 리소스로의 정확히 1개의 가변 참조(&mut T)
      >

      [ownership]: ownership.html
      [borrowing]: references-and-borrowing.html#borrowing

      이것이 바로 '불변성(immutability)'의 진짜 정의입니다: 그러면, 두개의 포인터를 동시에 가지는 것은 안전할까요? (원문 : is this safe to have two pointers to?) `Arc`의 경우에 대해서라면, 맞습니다. 변경은 완전히 구조체 그 안쪽에서만 일어납니다. 이것은 사용자가 직접 대면하지 않습니다. 이런 이유로, 이것은`clone()`을 통해 `&T`를 건네줍니다. 만약 이것이 `&mut T`을 건네준다면, 이것은 문제가 될 것입니다(역자 주 : 한 리소스에 대해 한 개의 불변 참조와 한 개의 가변 참조를 동시에 가지게 됩니다).

      다른 타입들, 그러니까 [`std::cell`][stdcell] 모듈 안에 있는 것들은, 그 반대입니다. 여기서는 내적 가변성(interior mutability)을 갖습니다. 예를 들자면:

      ```rust
      use std::cell::RefCell;

      let x = RefCell::new(42);

      let y = x.borrow_mut();
      ```

      [stdcell]: ../std/cell/index.html

      RefCell은 그 안쪽에 대한 `&mut` 참조를 `borrow_mut()` 메드를 통해 건네줍니다. 위험하지 않을까요? 만약 우리가 아래와 같이아래의 코드를 실행 한다면:

      ```rust,ignore
      use std::cell::RefCell;

      let x = RefCell::new(42);

      let y = x.borrow_mut();
      let z = x.borrow_mut();
      # (y, z);
      ```

      이것은 실제로 실행시간에 패닉을 일으킬 것입니다. 이것이 `RefCell`이 그렇게 동작하는 이유입니다: 이것은 러스트의 빌림 규칙을 실행시간에 강제하며, 만약 어길 시에는 `panic!`을 불러옵니다. 이것은 러스트의 가변성 규칙의 또다른 면에 대해 생각해보게 합니다. 우선 이것에 대해 이야기해 봅시다.

      ## 필드 단위 가변성(Field-level mutability)

      가변성은 빌림(`&mut`)과 바인딩(`let mut`)에 대한 특성입니다. 이것이 의미하는 바는, 예를 들자면, 어떤 [`struct`][struct]에 대해 어떤 필드(field)는 변경 가능(mutable)하고 어떤 것은 불변(immutable)하게 만들 수 없다는 것입니다.

      ```rust,ignore
      struct Point {
      x: i32,
      mut y: i32, // nope
      }
      ```

      구조체의 가변성은 그것의 바인딩에 의해 좌우됩니다:

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

      let mut a = Point { x: 5, y: 6 };

      a.x = 10;

      let b = Point { x: 5, y: 6};

      b.x = 10; // error: cannot assign to immutable field `b.x`
      ```

      [struct]: structs.html

      그러나, [`Cell`][cell]을 사용해서, 우리는 필드 단위 가변성을 흉내낼 수 있습니다:

      ```rust
      use std::cell::Cell;

      struct Point {
      x: i32,
      y: Cell,
      }

      let point = Point { x: 5, y: Cell::new(6) };

      point.y.set(7);

      println!("y: {:?}", point.y);
      ```

      [cell]: ../std/cell/struct.Cell.html

      이것은 `y: Cell { value: 7 }`을 출력합니다. 성공적으로 `y`를 갱신하였죠?

      release-channels
      # 4.11. 배포 채널 (Release Channels) - 8100%

      Rust 프로젝트는 배포판들을 관리하는 ‘배포 채널’이라고 불리는 개념을 사용합니다.
      당신의 프로젝트가 어떤 버전의 Rust를 사용할지 선택하는 과정을 이해하는 것은 중요합니다.

      # 개요 (Overview)

      Rust를 배포하는 세 가지 채널이 있습니다.

      * 야간 (Nightly)
      * 베타 (Beta)
      * 안정 (Stable)

      새 야간 배포는 하루에 한번 생성됩니다. 6주 마다, 최신 야간 릴리즈는 ‘베타’로 승격됩니다. 중요한 점은, 심각한 에러를 고치는 패치만 받을 것이라는 겁니다. 6주 뒤, 베타는 ‘안정’ 버전으로 승격되고, `1.x`의 다음 배포가 됩니다.

      이 과정은 병행해서 일어납니다. 6주 마다, 같은 날, 야간은 베타로, 베타는 안정으로 갑니다. `1.x`이 배포됨과 동시에, `1.(x + 1)-beta`가 배포되고, 야간은 `1.(x + 2)-nightly` 첫 버전이 됩니다.

      # 버전 선택하기 (Choosing a version)

      일반적으로 말하자면, 특별한 이유가 없다면, 안정 배포 채널을 이용하면 됩니다. 이 배포들은 일반적인 독자를 위한 목적입니다.

      하지만, Rust에서 관심에 따라, 대신에 야간을 선택할수도 있습니다. 기본적 트레이드 오프는 이것입니다. 야간 채널에서, 안정되지 않은 새로운 Rust 기능을 사용할 수 있습니다. 그러나, 불안정한 기능은 변경될 수 있기 때문에, 어떤 새로운 야간 배포도 여러분의 코드를 망가트릴 수 있습니다. 안정 배포를 사용한다면, 실험적인 기능을 사용할 수 없으나, Rust의 다음 배포는 변경되지 않기 때문에 심각한 이슈를 발생시키지 않을 것입니다.

      # CI를 통해 생태계 돕기 (Helping the ecosystem through CI)

      베타가 뭔가요? 안정된 배포 채널을 사용하는 모든 Rust 사용자들도 그들의 지속적 통합 시스템에서 베타 채널을 테스트하도록 독려합니다. 버그가 우연하게 발생하는 경우 팀에 알리도록 돕습니다.

      게다가, 야간 배포판으로 테스트하는 것은 버그를 더 빨리 잡을 수 있으므로, 세가지 빌드에 상관없이, 모든 채널을 통해 테스트해주신다면 감사하겠습니다.

      As an example, many Rust programmers use [Travis](https://travis-ci.org/) to
      test their crates, which is free for open source projects. Travis [supports
      Rust directly][travis], and you can use a `.travis.yml` file like this to
      test on all channels:

      ```yaml
      language: rust
      rust:
      - nightly
      - beta
      - stable

      matrix:
      allow_failures:
      - rust: nightly
      ```

      [travis]: http://docs.travis-ci.com/user/languages/rust/

      With this configuration, Travis will test all three channels, but if something
      breaks on nightly, it won’t fail your build. A similar configuration is
      recommended for any CI system, check the documentation of the one you’re
      using for more details
      예를 들자면, 많은 러스트 프로그래머들은 [Travis](https://travis-ci.org/)를 그들의 오픈소스 프로젝트를 시험 해보려고 사용합니다. Travis 는 러스트를 [직접 지원][travis]하고, 그리고 당신은 태스트할 체널들을 `.travis.yml`에서 볼수있습니다.

      ```yaml
      language: rust
      rust:
      - nightly
      - beta
      - stable

      matrix:
      allow_failures:
      - rust: nightly
      ```

      [travis]: http://docs.travis-ci.com/user/languages/rust/

      이 설정에서, Travis는 모든 3 체널들을 태스트 해볼것 이고, 만약 무언가 nightly빌드에서 실패했었어도, 빌드는 그대로 진행 될것입니다. 이러한 작업들은 어느 CI 시스탬에든 권장되고, 그리고 오류나 작업에 필요한 공식 문서들을 항상 참조 하시길 바랍니다
      .
      testing
      # 4.2. 테스팅 (Testing) - 95100%

      > 프로그램 테스팅은 버그의 존재를 보이는 매우 효과적인 방법일 수 있지만,
      > 버그가 없다는 걸 보이는 데는 절망적으로 부적합하다.
      >
      > 에츠허르 W. 데이크스트라, "The Humble Programmer" (1972)

      Rust 코드를 테스트하는 방법에 대해 이야기해봅시다. 여기에서는 Rust 코드를 테스트하는
      올바른 방법에 대해서 얘기하지는 않을 것입니다. 어떻게 테스트를 작성하는 것이 옳고 그른가는
      많은 의견들이 있지만, 이들 모두 같은 기본 도구를 쓰기 때문에, 여기에서는 이 도구를 쓰는
      문법을 보여 주려고 합니다.

      # `test` 속성

      간단히 말해서, Rust에서 테스트는 `test` 속성이 표기된 함수입니다. Cargo를 써서 `adder`라는 이름의 새 프로젝트를 만들어 볼까요?

      ```bash
      $ cargo new adder
      $ cd adder
      ```

      새 프로젝트를 만들면 Cargo는 자동으로 간단한 테스트를 생성해 줍니다.
      다음은 `src/lib.rs`의 내용입니다.

      ```rust
      #[test]
      fn it_works() {
      }
      ```

      `#[test]`를 눈여겨 보세요. 이 속성은 이 함수가 테스트 함수임을 나타냅니다. 지금은
      안에 아무 것도 없는데, 이러면 물론 테스트는 성공하겠죠! `cargo test`로 테스트를 돌릴 수
      있습니다.

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      Cargo가 테스트를 컴파일하고 실행했습니다. 여기에는 두 종류의 출력이 있는데, 하나는
      우리가 작성한 테스트에 해당하고, 다른 하나는 문서 테스트에 해당합니다. 문서 테스트에
      대해서는 나중에 이야기할 것입니다. 우선은 이 줄을 보지요.

      ```text
      test it_works ... ok
      ```

      `it_works`는 우리가 짠 테스트 함수의 이름입니다.

      ```rust
      fn it_works() {
      # }
      ```

      테스트 결과에 대한 요약도 볼 수 있습니다.

      ```text
      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
      ```

      그럼 왜 아무 것도 하지 않는 테스트가 성공하는 걸까요? `panic!`을 실행하지 않는 모든 테스트는
      성공한 걸로 치고, `panic!`을 실행하는 테스트는 실패한 걸로 칩니다. 위 테스트가 실패하도록
      만들어 봅시다.

      ```rust
      #[test]
      fn it_works() {
      assert!(false);
      }
      ```

      `assert!`는 Rust가 제공하는 매크로로, 인자 하나를 받아서 그게 `true`면 아무 일도 하지 않고,
      `false`면 `panic!`을 호출합니다. 한 번 테스트를 다시 돌려 보지요.

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test it_works ... FAILED

      failures:

      ---- it_works stdout ----
      thread 'it_works' panicked at 'assertion failed: false', /home/steve/tmp/adder/src/lib.rs:3



      failures:
      it_works

      test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

      thread '<main>' panicked at 'Some tests failed', /home/steve/src/rust/src/libtest/lib.rs:247
      ```

      Rust가 테스트가 실패했음을 알려 주었고...

      ```text
      test it_works ... FAILED
      ```

      결과 요약에도 반영되어 있네요.

      ```text
      test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
      ```

      또한 이는 0이 아닌 상태 코드를 반환하는데... We can use `$?` on OS X and Linux:

      ```bash
      $ echo $?
      101
      ```

      윈도우상에서 `cmd` 를 사용할때:

      ```bash
      > echo %ERRORLEVEL%
      ```

      PowerShell 를 사용할때:

      ```bash
      > echo $LASTEXITCODE # the code itself
      > echo $? # a boolean, fail or succeed
      ```

      이 상태 코드는 `cargo test`를 다른 도구와 연동할 때 유용합니다.

      테스트가 어떨 때 성공하고 어떨 때 실패하는지를 또 다른 속성으로 뒤집을 수 있습니다.
      바로 `should_panic`입니다.

      ```rust
      #[test]
      #[should_panic]
      fn it_works() {
      assert!(false);
      }
      ```

      이제 이 테스트는 `panic!`을 호출하면 성공하고 그렇지 않고 끝까지 실행되면 실패합니다.
      다시 실행해 보죠.

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      Rust는 `assert_eq!`라는 또 다른 매크로를 제공하는데, 이 매크로는 두 인자가 같은지 검사합니다.

      ```rust
      #[test]
      #[should_panic]
      fn it_works() {
      assert_eq!("Hello", "world");
      }
      ```

      이 테스트가 성공할까요 실패할까요? `should_panic` 속성이 있으므로, 이 테스트는 성공해야 합니다.

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      `should_panic` 테스트는 잘못 동작하기 쉬운데, 테스트가 미처 예상하지 못한 이유로
      실패하지 않는다는 걸 보장하기 어렵기 때문입니다. 이를 피하기 위해 `should_panic` 속성에
      `expected` 인자를 더할 수 있습니다. 이러면 실패 메시지에 지정한 텍스트가 들어 있을 때만
      테스트가 성공할 것입니다. 위 예제를 다음과 같이 좀 더 안전하게 쓸 수 있습니다.

      ```rust
      #[test]
      #[should_panic(expected = "assertion failed")]
      fn it_works() {
      assert_eq!("Hello", "world");
      }
      ```

      기본적인 건 이걸로 되었으니, '진짜' 테스트를 작성해 보지요.

      ```rust,ignore
      pub fn add_two(a: i32) -> i32 {
      a + 2
      }

      #[test]
      fn it_works() {
      assert_eq!(4, add_two(2));
      }
      ```

      이와 같이, 알려진 인자로 함수를 호출한 뒤 예상되는 결과와 비교하는 건
      `assert_eq!`를 쓰는 흔한 방법입니다.

      # `ignore` 속성

      가끔씩 몇몇개의 특정한 테스트는 실행하는데 많은 시간을 소모할 수 있습니다. 이러한 테스트들은 `ignore` 속성을 사용하여 기본적으로 비활성화 시켜둘 수 있습니다:

      ```rust
      #[test]
      fn it_works() {
      assert_eq!(4, add_two(2));
      }

      #[test]
      #[ignore]
      fn expensive_test() {
      // code that takes an hour to run
      }
      ```

      이제 위의 테스트를 실행하여 보면 `it_works` 는 실행되지만, `expensive_test` 는 실행되지 않는것을 볼 수 있습니다:

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 2 tests
      test expensive_test ... ignored
      test it_works ... ok

      test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      expensive tests 는 명시적으로 `cargo test -- --ignored`를 사용하여 실행할 수 있습니다:

      ```bash
      $ cargo test -- --ignored
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test expensive_test ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      `--ignored` 인자는 cargo 를 위한 것이 아닌 테스트 바이너리를 위한 인자입니다.
      이것이 커맨드가 `cargo test -- --ignored` 인 이유 입니다.

      # `tests` 모듈

      우리가 위에서 작성한 예제 중에 자연스럽지 않은 부분이 하나 있는데, 그것은 `tests` 모듈을 빼먹은 것입니다. 우리가 작성한 예제를 자연스럽게 고치면 다음과 같습니다.

      ```rust,ignore
      pub fn add_two(a: i32) -> i32 {
      a + 2
      }

      #[cfg(test)]
      mod tests {
      use super::add_two;

      #[test]
      fn it_works() {
      assert_eq!(4, add_two(2));
      }
      }
      ```

      몇가지가 바뀌었는데, 첫번째는 `cfg` 속성과 함께 `mod tests`를 도입한 것입니다. 이 모듈은 모든 우리의 테스트들을 함께 묶는 것을 허용하며, 필요하다면 helper function들을 정의할 수 있도록 해주고, 이것들이 우리 크레이트의 일부분이 되지 않도록 해 줍니다. `cfg` 속성은 우리가 테스트를 진행할 때만 테스트 코드를 컴파일하도록 합니다. 이것은 컴파일하는 시간을 절약해주며, 우리의 테스트가 완전히 일반 빌드(normal build)에서 제외되는 것을 보장해 줍니다.

      두번째 차이점은 `use` 선언입니다. 우리가 안쪽 모듈의 안에 있기 때문에, 우리는 우리가 테스트할 함수를 스코프(scope) 안으로 가져올 필요가 있습니다. 만약 큰 모듈에 대해서라면 모든 함수를 일일이 추가하는 것은 무척 짜증나는 작업이 될 것이고, 따라서 glob을 사용할 필요가 있습니다. 이 기능을 사용하도록 `src/lib.rs`를 고쳐봅시다.

      ```rust,ignore
      pub fn add_two(a: i32) -> i32 {
      a + 2
      }

      #[cfg(test)]
      mod tests {
      use super::*;

      #[test]
      fn it_works() {
      assert_eq!(4, add_two(2));
      }
      }
      ```

      `use`가 사용된 행을 확인해봅시다. '\*'가 보입니까? 이제 테스트를 해 봅시다.

      ```bash
      $ cargo test
      Updating registry `https://github.com/rust-lang/crates.io-index`
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test tests::it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      잘 돌아갑니다!

      현재의 관례상, `tests` 모듈은 자그마한 개별 기능을 시험하는 테스트들을 넣는데 주로
      쓰입니다. 이른바 "유닛" 테스트인데요, 하지만 "통합" 테스트라면 어떻게 할까요?
      `tests` 디렉토리는 바로 이 용도로 쓰입니다.

      # `tests` 디렉토리

      통합 테스트를 작성해 봅시다. 먼저 `tests` 디렉토리를 만들고, `tests/lib.rs` 파일을
      안에 만들어서 내용을 이렇게 채웁니다.

      ```rust,ignore
      extern crate adder;

      #[test]
      fn it_works() {
      assert_eq!(4, adder::add_two(2));
      }
      ```

      지금껏 짰던 테스트와 비슷해 보이지만 조금 다른 게 있습니다. 맨 위에 `extern crate adder`가
      들어간 게 보일 것입니다. `tests` 디렉토리 안에 있는 테스트들은 완전히 독립된 crate이므로,
      우리가 짠 라이브러리를 테스트하려면 먼저 불러 들여야 합니다. 라이브러리를 쓰는 방법을 그대로
      테스트하기 때문에 `tests`는 통합 테스트를 넣기에 좋은 장소입니다.

      실행해 보지요.

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/you/projects/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test tests::it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Running target/lib-c18e7d3494509e74

      running 1 test
      test it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 0 tests

      test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
      ```

      이제 출력이 세 개로 늘어났습니다. 원래 짰던 테스트는 그대로, 새 테스트가 추가되었습니다.

      `tests` 디렉토리만 있으면 됩니다. 모든 것들이 tests에 집
      중되어 있기 때문에, `tests`모듈은 여기에 필요치 않습니다.
      That's all there is to the `tests` directory. The `tests` module isn't needed
      here, since the whole thing is focused on tests.

      이제 마지막으로 세번째 부분인 문서 테스트를 확인해 봅시다.
      Let's finally check out that third section: documentation tests

      이제 마지막으로 세번째 부분인 문서 테스트를 확인해 봅시다
      .

      # 문서 테스트

      문서와 예제보다 중요한 것은 없습니다. 문서가 쓰여진 이후에 코드가 변경되었기 때문에 작동하지 않는 예제보다 나쁜 것은 없습니다. 이런 상황을 방지하기 위해, 러스트는 당신의 문서에서 자동적으로 실행되는 예제를 지원합니다(**note:** this only works in library crates, not binary crates참고:** 이건 라이브러리 Crate들에서만 작동합니다. 바이너리 Crate에선 작동하지않습니다). 여기에 구체화돤 `src/lib.rs`가 예제와 함꼐 있습니다.

      ```rust,ignore
      //! The `adder` crate provides functions that add numbers to other numbers.
      //!
      //! # Examples
      //!
      //! ```
      //! assert_eq!(4, adder::add_two(2));
      //! ```

      /// This function adds two to its argument.
      ///
      /// # Examples
      ///
      /// ```
      /// use adder::add_two;
      ///
      /// assert_eq!(4, add_two(2));
      /// ```
      pub fn add_two(a: i32) -> i32 {
      a + 2
      }

      #[cfg(test)]
      mod tests {
      use super::*;

      #[test]
      fn it_works() {
      assert_eq!(4, add_two(2));
      }
      }
      ```

      모듈 레벨 문서인 `//!`와 함수 레벨 문서인 `///`를 주목하십시오. Rust의 문서 지원은 주석 안에 Markdown 문법을 사용하는 것을 지원하며, 따라서 세개의 역따옴표(grave)는 코드 블럭을 뜻합니다. 위의 코드와 같이, 그 아래에 예제를 붙여 `# Examples` 섹션을 첨가하는 것이 관습입니다.

      테스트를 다시 한번 진행해 봅시다.

      ```bash
      $ cargo test
      Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
      Running target/adder-91b3e234d4ed382a

      running 1 test
      test tests::it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Running target/lib-c18e7d3494509e74

      running 1 test
      test it_works ... ok

      test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

      Doc-tests adder

      running 2 tests
      test add_two_0 ... ok
      test _0 ... ok

      test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
      ```

      이제 우리는 3종류의 테스트 전부를 다뤘습니다! 문서 테스트의 이름들을 확인해봅시다: `_0`는 모듈 테스트를 위해 생성된 것이고, `add_two_0`는 함수 테스트를 위한 것입니다. 여기에 붙은 순서는 `add_two_1`와 같이 당신이 예제를 붙여나감에 따라 자동적으로 증가할 것입니다.
      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;
      ```

      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::
      ```

      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)
      ```

      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

      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);
      ```

      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);
      }
      }
      ```

      This will call the `Clone` trait’s `clone()` method, rather than `Foo`’s.