Merge changes from master into Privo

Privo authored
revision b115a57cd0da0dfaa817259491a4170bd6e6a591
About
### Rust 문서 한글화 프로젝트

- 본 프로젝트는 Mozilla에서 개발한 Rust 언어의 문서를 한글화하는 프로젝트입니다.
- 현재 작업중인 문서는Book 1.2.0 에서 [Book 1.24.0](http://doc.rust-lang.org/stable/book/) 이고,으로 업데이트 중입니다. (1부터 5.11까지는 1.4.0으로 업데이트 완료. 5.12부터는 아직 1.2.0 버전) [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)

- 최근 활발한 참여자
- [jenix21](https://www.penflip.com/jenix21)
- [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.3. 조건부 컴파일 (Conditional Compilation)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/conditional-compilation.md) - 30%
- [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%
- [4.9. Borrow and AsRef](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/borrow-and-asref.md) - 0%
- [5.2. 함수 (Functions)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/functions.md) - 50%
- [5.13. 열거형 (Enums)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/enums.md) - 0%
- [5.21. Drop](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/drop.md) - 0%
- [5.22. if let](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/if-let.md) - 0%
- [5.23. 트레잇 객체 (Trait Objects)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/trait-objects.md) - 5
13. 열거형 (Enums)](https://www.penflip.com/sarojaba/rust-doc-korean/blob/master/enums.md) - 0%
Contents
About.txt
readme.md
getting-started.md
installing-rust.md
hello-world.md
hello-cargo.md
learn-rust.md
guessing-game.md
dining-philosophers.md
rust-inside-other-languages.md
effective-rust.md
the-stack-and-the-heap.md
testing.md
conditional-compilation.md
documentation.md
iterators.md
concurrency.md
error-handling.md
choosing-your-guarantees.md
ffi.md
borrow-and-asref.md
release-channels.md
syntax-and-semantics.md
variable-bindings.md
functions.md
primitive-types.md
comments.md
if.md
loops.md
for-loops.md
while-loops.md
ownership.md
references-and-borrowing.md
lifetimes.md
mutability.md
structs.md
enums.md
match.md
patterns.md
method-syntax.md
vectors.md
strings.md
generics.md
traits.md
drop.md
if-let.md
trait-objects.md
closures.md
ufcs.md
crates-and-modules.md
concordance.md
borrow-and-asref
# 4.910. Borrow and AsRef

The
- 5%

[`Borrow`][borrow] and [`AsRef`][asref] traits are very similar, but
different. Here’s a quick refresher on what these two traits mean
트레잇은 매우 유사하지만 다릅니다. 두 개의 트레잇이 어떤것을 의미하는지에 대해 상기시켜 보도록 합시다.

[borrow]: ../std/borrow/trait.Borrow.html
[asref]: ../std/convert/trait.AsRef.html

# Borrow

The `Borrow` trait is used when you’re writing a datastructure, and you want to
use either an owned or borrowed type as synonymous for some purpose.

For example, [`HashMap`][hashmap] has a [`get` method][get] which uses `Borrow`:

```rust,ignore
fn get(&self, k: &Q) -> Option<&V>
where K: Borrow,
Q: Hash + Eq
```

[hashmap]: ../std/collections/struct.HashMap.html
[get]: ../std/collections/struct.HashMap.html#method.get

This signature is pretty complicated. The `K` parameter is what we’re interested
in here. It refers to a parameter of the `HashMap` itself:

```rust,ignore
struct HashMap {
```

The `K` parameter is the type of _key_ the `HashMap` uses. So, looking at
the signature of `get()` again, we can use `get()` when the key implements
`Borrow`. That way, we can make a `HashMap` which uses `String` keys,
but use `&str`s when we’re searching:

```rust
use std::collections::HashMap;

let mut map = HashMap::new();
map.insert("Foo".to_string(), 42);

assert_eq!(map.get("Foo"), Some(&42));
```

This is because the standard library has `impl Borrow for String`.

For most types, when you want to take an owned or borrowed type, a `&T` is
enough. But one area where `Borrow` is effective is when there’s more than one
kind of borrowed value. This is especially true of references and slices: you
can have both an `&T` or a `&mut T`. If we wanted to accept both of these types,
`Borrow` is up for it:

```rust
use std::borrow::Borrow;
use std::fmt::Display;

fn foo + Display>(a: T) {
println!("a is borrowed: {}", a);
}

let mut i = 5;

foo(&i);
foo(&mut i);
```

This will print out `a is borrowed: 5` twice.

# AsRef

The `AsRef` trait is a conversion trait. It’s used for converting some value to
a reference in generic code. Like this:

```rust
let s = "Hello".to_string();

fn foo>(s: T) {
let slice = s.as_ref();
}
```

# Which should I use?

We can see how they’re kind of the same: they both deal with owned and borrowed
versions of some type. However, they’re a bit different.

Choose `Borrow` when you want to abstract over different kinds of borrowing, or
when you’re building a datastructure that treats owned and borrowed values in
equivalent ways, such as hashing and comparison.

Choose `AsRef` when you want to convert something to a reference directly, and
you’re writing generic code.
choosing-your-guarantees
# 4.8. Choosing your Guarantees - 0%

One important feature of Rust as language is that it lets us control the costs and guarantees
of a program.

There are various “wrapper type” abstractions in the Rust standard library which embody
a multitude of tradeoffs between cost, ergonomics, and guarantees. Many let one choose between
run time and compile time enforcement. This section will explain a few selected abstractions in
detail.

Before proceeding, it is highly recommended that one reads about [ownership][ownership] and
[borrowing][borrowing] in Rust.

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

# Basic pointer types

## `Box`

[`Box`][box] is pointer which is “owned”, or a “box”. While it can hand
out references to the contained data, it is the only owner of the data. In particular, when
something like the following occurs:

```rust
let x = Box::new(1);
let y = x;
// x no longer accessible here
```

Here, the box was _moved_ into `y`. As `x` no longer owns it, the compiler will no longer allow the
programmer to use `x` after this. A box can similarly be moved _out_ of a function by returning it.

When a box (that hasn't been moved) goes out of scope, destructors are run. These destructors take
care of deallocating the inner data.

This is a zero-cost abstraction for dynamic allocation. If you want to allocate some memory on the
heap and safely pass around a pointer to that memory, this is ideal. Note that you will only be
allowed to share references to this by the regular borrowing rules, checked at compile time.

[box]: ../std/boxed/struct.Box.html

## `&T` and `&mut T`

These are immutable and mutable references respectively. They follow the “read-write lock”
pattern, such that one may either have only one mutable reference to some data, or any number of
immutable ones, but not both. This guarantee is enforced at compile time, and has no visible cost at
runtime. In most cases these two pointer types suffice for sharing cheap references between sections
of code.

These pointers cannot be copied in such a way that they outlive the lifetime associated with them.

## `*const T` and `*mut T`

These are C-like raw pointers with no lifetime or ownership attached to them. They just point to
some location in memory with no other restrictions. The only guarantee that these provide is that
they cannot be dereferenced except in code marked `unsafe`.

These are useful when building safe, low cost abstractions like `Vec`, but should be avoided in
safe code.

## `Rc`

This is the first wrapper we will cover that has a runtime cost.

[`Rc`][rc] is a reference counted pointer. In other words, this lets us have multiple "owning"
pointers to the same data, and the data will be dropped (destructors will be run) when all pointers
are out of scope.

Internally, it contains a shared “reference count” (also called “refcount”),
which is incremented each time the `Rc` is cloned, and decremented each time one of the `Rc`s goes
out of scope. The main responsibility of `Rc` is to ensure that destructors are called for shared
data.

The internal data here is immutable, and if a cycle of references is created, the data will be
leaked. If we want data that doesn't leak when there are cycles, we need a garbage collector.

#### Guarantees

The main guarantee provided here is that the data will not be destroyed until all references to it
are out of scope.

This should be used when we wish to dynamically allocate and share some data (read-only) between
various portions of your program, where it is not certain which portion will finish using the pointer
last. It's a viable alternative to `&T` when `&T` is either impossible to statically check for
correctness, or creates extremely unergonomic code where the programmer does not wish to spend the
development cost of working with.

This pointer is _not_ thread safe, and Rust will not let it be sent or shared with other threads.
This lets one avoid the cost of atomics in situations where they are unnecessary.

There is a sister smart pointer to this one, `Weak`. This is a non-owning, but also non-borrowed,
smart pointer. It is also similar to `&T`, but it is not restricted in lifetime—a `Weak`
can be held on to forever. However, it is possible that an attempt to access the inner data may fail
and return `None`, since this can outlive the owned `Rc`s. This is useful for cyclic
data structures and other things.

#### Cost

As far as memory goes, `Rc` is a single allocation, though it will allocate two extra words (i.e.
two `usize` values) as compared to a regular `Box` (for "strong" and "weak" refcounts).

`Rc` has the computational cost of incrementing/decrementing the refcount whenever it is cloned
or goes out of scope respectively. Note that a clone will not do a deep copy, rather it will simply
increment the inner reference count and return a copy of the `Rc`.

[rc]: ../std/rc/struct.Rc.html

# Cell types

`Cell`s provide interior mutability. In other words, they contain data which can be manipulated even
if the type cannot be obtained in a mutable form (for example, when it is behind an `&`-ptr or
`Rc`).

[The documentation for the `cell` module has a pretty good explanation for these][cell-mod].

These types are _generally_ found in struct fields, but they may be found elsewhere too.

## `Cell`

[`Cell`][cell] is a type that provides zero-cost interior mutability, but only for `Copy` types.
Since the compiler knows that all the data owned by the contained value is on the stack, there's
no worry of leaking any data behind references (or worse!) by simply replacing the data.

It is still possible to violate your own invariants using this wrapper, so be careful when using it.
If a field is wrapped in `Cell`, it's a nice indicator that the chunk of data is mutable and may not
stay the same between the time you first read it and when you intend to use it.

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

let x = Cell::new(1);
let y = &x;
let z = &x;
x.set(2);
y.set(3);
z.set(4);
println!("{}", x.get());
```

Note that here we were able to mutate the same value from various immutable references.

This has the same runtime cost as the following:

```rust,ignore
let mut x = 1;
let y = &mut x;
let z = &mut x;
x = 2;
*y = 3;
*z = 4;
println!("{}", x);
```

but it has the added benefit of actually compiling successfully.

#### Guarantees

This relaxes the “no aliasing with mutability” restriction in places where it's
unnecessary. However, this also relaxes the guarantees that the restriction provides; so if your
invariants depend on data stored within `Cell`, you should be careful.

This is useful for mutating primitives and other `Copy` types when there is no easy way of
doing it in line with the static rules of `&` and `&mut`.

`Cell` does not let you obtain interior references to the data, which makes it safe to freely
mutate.

#### Cost

There is no runtime cost to using `Cell`, however if you are using it to wrap larger (`Copy`)
structs, it might be worthwhile to instead wrap individual fields in `Cell` since each write is
otherwise a full copy of the struct.


## `RefCell`

[`RefCell`][refcell] also provides interior mutability, but isn't restricted to `Copy` types.

Instead, it has a runtime cost. `RefCell` enforces the read-write lock pattern at runtime (it's
like a single-threaded mutex), unlike `&T`/`&mut T` which do so at compile time. This is done by the
`borrow()` and `borrow_mut()` functions, which modify an internal reference count and return smart
pointers which can be dereferenced immutably and mutably respectively. The refcount is restored when
the smart pointers go out of scope. With this system, we can dynamically ensure that there are never
any other borrows active when a mutable borrow is active. If the programmer attempts to make such a
borrow, the thread will panic.

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

let x = RefCell::new(vec![1,2,3,4]);
{
println!("{:?}", *x.borrow())
}

{
let mut my_ref = x.borrow_mut();
my_ref.push(1);
}
```

Similar to `Cell`, this is mainly useful for situations where it's hard or impossible to satisfy the
borrow checker. Generally we know that such mutations won't happen in a nested form, but it's good
to check.

For large, complicated programs, it becomes useful to put some things in `RefCell`s to make things
simpler. For example, a lot of the maps in [the `ctxt` struct][ctxt] in the rust compiler internals
are inside this wrapper. These are only modified once (during creation, which is not right after
initialization) or a couple of times in well-separated places. However, since this struct is
pervasively used everywhere, juggling mutable and immutable pointers would be hard (perhaps
impossible) and probably form a soup of `&`-ptrs which would be hard to extend. On the other hand,
the `RefCell` provides a cheap (not zero-cost) way of safely accessing these. In the future, if
someone adds some code that attempts to modify the cell when it's already borrowed, it will cause a
(usually deterministic) panic which can be traced back to the offending borrow.

Similarly, in Servo's DOM there is a lot of mutation, most of which is local to a DOM type, but some
of which crisscrosses the DOM and modifies various things. Using `RefCell` and `Cell` to guard all
mutation lets us avoid worrying about mutability everywhere, and it simultaneously highlights the
places where mutation is _actually_ happening.

Note that `RefCell` should be avoided if a mostly simple solution is possible with `&` pointers.

#### Guarantees

`RefCell` relaxes the _static_ restrictions preventing aliased mutation, and replaces them with
_dynamic_ ones. As such the guarantees have not changed.

#### Cost

`RefCell` does not allocate, but it contains an additional "borrow state"
indicator (one word in size) along with the data.

At runtime each borrow causes a modification/check of the refcount.

[cell-mod]: ../std/cell/
[cell]: ../std/cell/struct.Cell.html
[refcell]: ../std/cell/struct.RefCell.html
[ctxt]: ../rustc/middle/ty/struct.ctxt.html

# Synchronous types

Many of the types above cannot be used in a threadsafe manner. Particularly, `Rc` and
`RefCell`, which both use non-atomic reference counts (_atomic_ reference counts are those which
can be incremented from multiple threads without causing a data race), cannot be used this way. This
makes them cheaper to use, but we need thread safe versions of these too. They exist, in the form of
`Arc` and `Mutex`/`RWLock`

Note that the non-threadsafe types _cannot_ be sent between threads, and this is checked at compile
time.

There are many useful wrappers for concurrent programming in the [sync][sync] module, but only the
major ones will be covered below.

[sync]: ../std/sync/index.html

## `Arc`

[`Arc`][arc] is just a version of `Rc` that uses an atomic reference count (hence, "Arc").
This can be sent freely between threads.

C++'s `shared_ptr` is similar to `Arc`, however in the case of C++ the inner data is always mutable.
For semantics similar to that from C++, we should use `Arc>`, `Arc>`, or
`Arc>`[^4] (`UnsafeCell` is a cell type that can be used to hold any data and has
no runtime cost, but accessing it requires `unsafe` blocks). The last one should only be used if we
are certain that the usage won't cause any memory unsafety. Remember that writing to a struct is not
an atomic operation, and many functions like `vec.push()` can reallocate internally and cause unsafe
behavior, so even monotonicity may not be enough to justify `UnsafeCell`.

[^4]: `Arc>` actually won't compile since `UnsafeCell` isn't `Send` or `Sync`, but we can wrap it in a type and implement `Send`/`Sync` for it manually to get `Arc>` where `Wrapper` is `struct Wrapper(UnsafeCell)`.

#### Guarantees

Like `Rc`, this provides the (thread safe) guarantee that the destructor for the internal data will
be run when the last `Arc` goes out of scope (barring any cycles).

#### Cost

This has the added cost of using atomics for changing the refcount (which will happen whenever it is
cloned or goes out of scope). When sharing data from an `Arc` in a single thread, it is preferable
to share `&` pointers whenever possible.

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

## `Mutex` and `RwLock`

[`Mutex`][mutex] and [`RwLock`][rwlock] provide mutual-exclusion via RAII guards (guards are
objects which maintain some state, like a lock, until their destructor is called). For both of
these, the mutex is opaque until we call `lock()` on it, at which point the thread will block
until a lock can be acquired, and then a guard will be returned. This guard can be used to access
the inner data (mutably), and the lock will be released when the guard goes out of scope.

```rust,ignore
{
let guard = mutex.lock();
// guard dereferences mutably to the inner type
*guard += 1;
} // lock released when destructor runs
```


`RwLock` has the added benefit of being efficient for multiple reads. It is always safe to have
multiple readers to shared data as long as there are no writers; and `RwLock` lets readers acquire a
"read lock". Such locks can be acquired concurrently and are kept track of via a reference count.
Writers must obtain a "write lock" which can only be obtained when all readers have gone out of
scope.

#### Guarantees

Both of these provide safe shared mutability across threads, however they are prone to deadlocks.
Some level of additional protocol safety can be obtained via the type system.

#### Costs

These use internal atomic-like types to maintain the locks, which are pretty costly (they can block
all memory reads across processors till they're done). Waiting on these locks can also be slow when
there's a lot of concurrent access happening.

[rwlock]: ../std/sync/struct.RwLock.html
[mutex]: ../std/sync/struct.Mutex.html
[sessions]: https://github.com/Munksgaard/rust-sessions

# Composition

A common gripe when reading Rust code is with types like `Rc>>` (or even more more
complicated compositions of such types). It's not always clear what the composition does, or why the
author chose one like this (and when one should be using such a composition in one's own code)

Usually, it's a case of composing together the guarantees that you need, without paying for stuff
that is unnecessary.

For example, `Rc>` is one such composition. `Rc` itself can't be dereferenced mutably;
because `Rc` provides sharing and shared mutability can lead to unsafe behavior, so we put
`RefCell` inside to get dynamically verified shared mutability. Now we have shared mutable data,
but it's shared in a way that there can only be one mutator (and no readers) or multiple readers.

Now, we can take this a step further, and have `Rc>>` or `Rc>>`. These
are both shareable, mutable vectors, but they're not the same.

With the former, the `RefCell` is wrapping the `Vec`, so the `Vec` in its entirety is
mutable. At the same time, there can only be one mutable borrow of the whole `Vec` at a given time.
This means that your code cannot simultaneously work on different elements of the vector from
different `Rc` handles. However, we are able to push and pop from the `Vec` at will. This is
similar to an `&mut Vec` with the borrow checking done at runtime.

With the latter, the borrowing is of individual elements, but the overall vector is immutable. Thus,
we can independently borrow separate elements, but we cannot push or pop from the vector. This is
similar to an `&mut [T]`[^3], but, again, the borrow checking is at runtime.

In concurrent programs, we have a similar situation with `Arc>`, which provides shared
mutability and ownership.

When reading code that uses these, go in step by step and look at the guarantees/costs provided.

When choosing a composed type, we must do the reverse; figure out which guarantees we want, and at
which point of the composition we need them. For example, if there is a choice between
`Vec>` and `RefCell>`, we should figure out the tradeoffs as done above and pick
one.

[^3]: `&[T]` and `&mut [T]` are _slices_; they consist of a pointer and a length and can refer to a portion of a vector or array. `&mut [T]` can have its elements mutated, however its length cannot be touched.
comments
# 5.4. 주석 (Comments) - 1080%

이제 여러분들은 몇 개의 함수들을 가지게 되었고, 주석에 대해 배우는 것은 좋은 생각입니다. 주석은 다른 프로그래머에게 여러분의 코드에 관한 것들을 설명하는데 도움을 주도록 남기는 것입니다. 컴파일러는 주석 대부분을 무시합니다.

Rust는 두 종류의 주석(*한 줄 주석*과 *문서 주석*)을 가지고 있습니다.

```rust
// Line comments are anything after ‘//’ and extend to the end of the line.

let x = 5; // this is also a line comment.

// If you have a long explanation for something, you can put line comments next
// to each other. Put a space between the // and your comment so that it’s
// more readable.
```

나머지 주석의 종류는 문서 주석입니다. 문서 주석은 `//` 대신에 `///`를 사용하고, 내용으로 마크다운 표기를 지원합니다.

```rust
/// Adds one to the number given.
///
/// # Examples
///
/// ```
/// let five = 5;
///
/// assert_eq!(6, add_one(5));
/// # fn add_one(x: i32) -> i32 {
/// # x + 1
/// # }
/// ```
fn add_one(x: i32) -> i32 {
x + 1
}
```

There is another style of doc comment, `//!`, to comment containing items (e.g.
crates, modules or functions), instead of the items following it. Commonly used
inside crates root (lib.rs) or modules root (mod.rs):

```
//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
```

문서 주석을 작성할 때, 사용 예제를 제공하면 아주, 아주 도움이 됩니다. 여기 새로운 매크로 `assert_eq!`를 사용한다는 것을 알려줍니다. 이 것은 두 값을 비교해서, 서로 다르면 `panic!`을 발생시킵니다. 이것은 문서화에 아주 도움이 됩니다. 값이 `false`라면 `panic!`을 발생시키는 `assert!` 매크로도 있습니다.

문서 주석에서 HTML 문서를 생성하고, 테스트로서 코드 예제를 실행하기 위해 [rustdoc](documentation.html) 도구를 사용할 수 있습니다.
concurrency
# 4.6. 동시성 (Concurrency) - 1090%

동시성과 병렬성은 컴퓨터 과학에서 무척이나 중요한 주제이며, 오늘날 실무에서도 중요하게 취급됩니다. 컴퓨터의 코어 수는 날이 갈수록 늘어나고 있지만 아직도 많은 프로그래머들은 이 코어들을 충분히 활용할 준비가 되어있지 않습니다.

Rust의 메모리 보호(memory safety)는 동시성 환경에서도 똑같이 적용됩니다. 동시처리(concurrent) Rust 프로그램에서도 필수적으로 데이터 경합이 없도록 메모리 보호처리가 이루어져야 합니다. 여기서 Rust의 타입 시스템이 동시처리 코드에 대해 컴파일 단계에서 검증할 수 있도록 도와줍니다.

Rust의 동시성 기능에 대해 이야기하기 전에, 한 가지 짚고 넘어가야 할 것이 있습니다. 바로 Rust는 이 모든아주 주요한 것이 언어가 아닌 표준 라이브러리를 통해 제공될 정도로 저수준이란 점입니다. 그렇기 때문에 만약 Rust가 동시성을 다루는 방식이 어딘가 마음에 들지 않는다면 직접 구현할 수도 있습니다.
[mio](https://github.com/carllerche/mio)는 이 원칙이 적용된 실제 예입니다.

## 배경지식: `Send` 와 `Sync`

동시처리 프로그램은 검증(reason about)하기 어렵습니다. 하지만 Rust의 강하고(strong), 정적(static) 타입 시스템이 검증을 도와줍니다. 예를 들어 Rust는 두 트레잇을 제공해 동시성을 가질지도 모르는 코드를 이해하도록 돕습니다.

### `Send`

여기서 다룰 첫 트레잇은 [`Send`](../std/marker/trait.Send.html)입니다. 타입 `T`가 `Send`를 구현(implement)하는 건 이 타입이 스레드 사이에서 소유권을 안전하게 넘겨줄 수 있다고 컴파일러에게 알려주는 것입니다.

이를 위해 일정한 제한을 두는 것이 중요합니다. 예를 들어 만약 두 스레드 사이에 채널이 있다면 어떤 데이터를 다른 스레드에게 채널을 통해 보내고 싶을 수도 있습니다. 그러므로 우리는 그 타입을 위해 `Send`를 반드시 구현해야 합니다.

반대로, 스레드 안전하지 않은 라이브러리를 FFI로 감쌀 때는 `Send`를 구현하지 않아야 컴파일러가 현재 스레드를 떠나지 않도록 강제할 것입니다.

### `Sync`

두 번째 트레잇은 [`Sync`](../std/marker/trait.Sync.html)라고 합니다. 타입`T`가 `Sync`를 구현하는 건 이 타입을 가진 무언가가 여러 스레드에서 동시에 사용돼도 메모리 불안전성을 절대 불러오지 않는다고 컴파일러에게 알려주는 것입니다.

예를 들어, 원자적 참조 계수(atomic reference count)를 가진 불변 데이터(immutable data)의 공유는 스레드 안전합니다. Rust는 `Arc`와 같은 타입을 제공하여 `Sync`를 구현, 스레드 사이의 공유를 안전하게 합니다.

이 두 트레잇은 타입 시스템으로 하여금 동시성을 지닌 코드의 속성에 대한 강한 보장을 가능하게 합니다. 왜인지 설명하기 전에 먼저 동시처리 Rust 프로그램을 만드는 법을 배워보도록 합시다!

## Threads

러스트의 표준 라이브러리 중에는 동시처리가 가능하도록 하는 스레드 관련 라이브러리들이 있습니다. 가장 간단한 예시는 `std::thread`입니다:

```rust
use std::thread;

fn main() {
thread::spawn(|| {
println!("Hello from a thread!");
});
}
```

`thread::spawn()`은 클로저를 받아, 새로운 스레드 안에서 실행하는 메소드입니다. 자식 스레드(child thread)들이 끝날때까지 기다리고 그 결과들을 받아올 수 있도록 해주는 핸들(handle)을 반환값으로 가집니다.

```rust
use std::thread;

fn main() {
let handle = thread::spawn(|| {
"Hello from a thread!"
});

println!("{}", handle.join().unwrap());
}
```

많은 언어들이 스레드들을 사용할 수 있도록 되어있지만, 매우 위험합니다. 공유된 가변 상태(shared mutable state)때문에 발생하는 에러를 어떻게 해결할 것인가에 대한 책들만 해도 수십권이 될 것입니다. 러스트는 타입 시스템, 더 나아가 컴파일 차원에서 데이터 레이스를 방지하여 해결합니다. 스레드 간에 어떻게 공유가 이루어지는지 보도록 합시다.

## Safe Shared Mutable State

러스트의 타입 시스템 덕분에, 마치 거짓말 같이 들리는 능력을 얻었습니다:
"안전한 공유된 가변 상태(safe shared mutable state)"
많은 프로그래머들이 공유된 가변 상태는 매우, 매우 나쁘다는 것을 공감하고 있습니다.
누군가는 이렇게 말합니다:

>공유된 가변 상태는 모든 악의 근원(root of all evil)이다. 대부분의 언어들은 이 문제를
>'가변'의 관점에서 해결하려 한다, 그러나 러스트는 '공유'의 관점에서 문제를 해결했다.

같은 맥락으로 [소유권 시스템](ownership.html)은 포인터를 잘못 사용하는 것을 방지함으로써 동시성의 악명 높은 문제, 데이터 레이스를 해결하는 데에도 도움을 줍니다.

한 예로, 데이터 레이스 문제를 가진 러스트 프로그램이 있습니다. 이것은 컴파일 자체가 되지 않을 것입니다:

```ignore
use std::thread;

fn main() {
let mut data = vec![1, 2, 3];

for i in 0..3 {
thread::spawn(move || {
data[i] += 1;
});
}

thread::sleep_ms(50);
}
```

이런 에러 메시지를 출력합니다:

```text
8:17 error: capture of moved value: `data`
data[i] += 1;
^~~~
```

이 경우에, 우리 코드가 _아마_ 안전하다고 생각할지도 모르지만, 러스트는 그렇지 않은가 봅니다. 그리고 실제로 안전하지 않습니다: 각 스레드가 `data`의 참조를 가지고 있고, 참조의 소유권도 가지고 있으니, 소유자가 셋이나 있습니다! 좋지 않군요. 이것을 원자적 참조 계수 포인터(atomic reference counted pointer)라 불리는 `Arc` 타입을 사용해 해결할 수 있습니다. 여기서 원자적(atomic)은 스레드들 간에 공유가 이루어지는 것에 안전하다는 것을 의미합니다.

`Arc`는 원자적(atomic) 속성에서 하나 더 가정합니다: 바로 그 내용물이 `Sync`라고 가정하는 것입니다. 그렇지만 여기서 우리는 값을 변경할 수 있도록 하고 싶습니다. 때문에 반드시 한번에 한 사람만 값을 변경할 수 있다는 것을 보장하는 타입이 필요합니다. `Mutex` 타입입니다. 여기 우리의 수정된 코드가 있습니다. 여전히 작동하지 않지만, 이유가 다릅니다:

```ignore
use std::thread;
use std::sync::Mutex;

fn main() {
let mut data = Mutex::new(vec![1u32, 2, 3]);

for i in 0..3 {
let data = data.lock().unwrap();
thread::spawn(move || {
data[i] += 1;
});
}

thread::sleep_ms(50);
}
```

에러 메세지:

```text
:9:9: 9:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` [E0277]
:11 thread::spawn(move || {
^~~~~~~~~~~~~
:9:9: 9:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec>` cannot be sent between threads safely
:11 thread::spawn(move || {
^~~~~~~~~~~~~
```

보셨듯이, [`Mutex`](../std/sync/struct.Mutex.html)는 다음의 명세를 가진 [`lock`](../std/sync/struct.Mutex.html#method.lock) 메소드를 가지고 있습니다.

```ignore
fn lock(&self) -> LockResult>
```

`MutexGuard`에 `Send`가 구현되지 않았기 때문에, guard를 스레드 너머로 전달할 수 없어 에러가 발생하는 것입니다.

`Arc`를 사용해 고쳐보죠. 작동하는 버전입니다:
Rust knows this wouldn't be safe! If we had a reference to `data` in each
thread, and the thread takes ownership of the reference, we'd have three
owners!

So, we need some type that lets us have more than one reference to a value and
that we can share between threads, that is it must implement `Sync`.

We'll use `Arc`, rust's standard atomic reference count type, which
wraps a value up with some extra runtime bookkeeping which allows us to
share the ownership of the value between multiple references at the same time.

The bookkeeping consists of a count of how many of these references exist to
the value, hence the reference count part of the name.

The Atomic part means `Arc` can safely be accessed from multiple threads.
To do this the compiler guarantees that mutations of the internal count use
indivisible operations which can't have data races.

```ignore
use std::thread;
use std::sync::Arc;

fn main() {
let mut data = Mutex::new(vec![1, 2, 3]);

for i in 0..3 {
let data = data.clone();
thread::spawn(move || {
data[i] += 1;
});
}

thread::sleep_ms(50);
}
```

We now call `clone()` on our `Arc`, which increases the internal count.
This handle is then moved into the new thread.

And... still gives us an error.

```text
:11:24 error: cannot borrow immutable borrowed content as mutable

:11 data[i] += 1;
^~~~
```

`Arc` assumes one more property about its contents to ensure that it is safe
to share across threads: it assumes its contents are `Sync`. This is true for
our value if it's immutable, but we want to be able to mutate it, so we need
something else to persuade the borrow checker we know what we're doing.

It looks like we need some type that allows us to safely mutate a shared value,
for example a type that that can ensure only one thread at a time is able to
mutate the value inside it at any one time.

For that, we can use the `Mutex` type!


```rust
use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
let data = Arc::new(Mutex::new(vec![1, 2, 3]));

for i in 0..3 {
let data = data.clone();
thread::spawn(move || {
let mut data = data.lock().unwrap();
data[i] += 1;
});
}

thread::sleep_ms(50);
}
```

`Arc`의 `clone()`을 호출합니다. 이것은 내부 계수(internal count)를 상승시킵니다. 그리고 이 핸들은 새로운 스레드로 옮겨집니다. 스레드의 몸체 부분을 좀 더 자세히 보도록 하죠:

```rust
# use std::sync::{Arc, Mutex};
# use std::thread;
# fn main() {
# let data = Arc::new(Mutex::new(vec![1, 2, 3]));
# for i in 0..3 {
# let data = data.clone();
thread::spawn(move || {
let mut data = data.lock().unwrap();
data[i] += 1;
});
# }
# thread::sleep_ms(50);
# }
```

먼저, Mutex의 잠금을 얻는 `lock()`을 호출합니다. 실패할 수도 있기 때문에, `Result`를 반환합니다. 그리고 이것은 단지 예제이기 때문에, `unwrap()`을 사용해 데이터의 참조를 얻어옵니다. 실제 코드는 여기서 좀 더 에러 핸들링에 엄격해야 합니다. 우리가 잠금을 가지고 있기 때문에, 여기서는 마음대로 값을 수정할 수 있습니다.

마지막으로 스레드들이 실행하고 있는 중에, 짧은 타이머를 기다립니다. 그러나 이것이 최선은 아닙니다: 딱 맞는 시간을 기다릴 수도 있게 되겠지만, 스레드들이 계산을 끝내는데 얼마나 걸리느냐에 따라 대부분 들쭉날쭉하게 기다릴 것입니다. (더 늦거나 빠르게)

더 정확한 방법 중 하나는 스레드들간의 동기화를 제공하는 러스트 표준 라이브러리를 사용하는 것입니다. 그 중 하나를 소개하죠: 채널(channels)

## Channels

이것이 특정한 시간을 기다리기보다 채널을 사용해 동기화를 한 코드입니다:

```rust
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc;

fn main() {
let data = Arc::new(Mutex::new(0));

let (tx, rx) = mpsc::channel();

for _ in 0..10 {
let (data, tx) = (data.clone(), tx.clone());

thread::spawn(move || {
let mut data = data.lock().unwrap();
*data += 1;

tx.send(());
});
}

for _ in 0..10 {
rx.recv();
}
}
```

`mpsc::channel()`를 사용해 새로운 채널을 생성했습니다. `send`에 간단한 `()`을 보내주었고, 10개가 돌아오기를 기다립니다.

채널은 제네릭 신호(generic signal)를 보내기 때문에, 어떤 데이터든지 `Send`에 써서 보낼 수 있습니다!

```rust
use std::thread;
use std::sync::mpsc;

fn main() {
let (tx, rx) = mpsc::channel();

for _ in 0..10 {
let tx = tx.clone();

thread::spawn(move || {
let answer = 42;

tx.send(answer);
});
}

rx.recv().ok().expect("Could not receive answer");
}
```

복사할 수 있기 때문에 `u32`를 `Send`에 보냈습니다. 스레드를 만들고, answer를 계산하기를 요청하고, `send()`로 answer를 채널로 보냅니다.


## Panics

`panic!`은 현재 실행중인 스레드를 멈춥니다. 간단한 격리(isolation) 매커니즘의 일환으로 러스트의 스레드를 사용할 수 있습니다:

```rust
use std::thread;

let resulthandle = thread::spawn(move || {
panic!("oops!");
}).join();

let result = handle.join();

assert!(result.is_err());
```

`Thread.join()`은 우리의 `Thread`는 스레드가 패닉되었는지 체크해주는 `Result`를 돌려줍니다.
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

You can also set another attribute based on a `cfg` variable with `cfg_attr`:

```rust
#[cfg_attr(a, b)]
# fn foo() {}
```

Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwise
`cfg_attr`라는 명령어를 사용해서 `cfg` 에 기반한 다른 속성들을 설정하는 것도 가능합니다.

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

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

# cfg!

The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
elsewhere in your code, too:
를 아래와 같은 방식으로 자신의 코드에 추가할 수 있습니다.

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

[compilerplugins]: compiler-plugins.html

These will be replaced by a프로젝트의 설정값에 따라 위 선택문들은 컴파일 중 `true` or `false` at compile-time, depending on the
configuration settings.
로 대체됩니다.

crates-and-modules
# 5.26. Crates and Modules

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

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

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.

Also, note that we `pub use`d before we declared our `mod`s. Rust requires that
`use` declarations go first.

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: さようなら
```
dining-philosophers
# 3.2. 철학자들의 만찬 (Dining Philosophers) - 100%

우리의 두 번째 프로젝트를 위해, 고전적인 동시성 문제를 살펴봅시다. '철학자들의 만찬'이라 불리는 문제인데요. 이 문제는 다익스트라_Dijkstra_에 의해 1965년 처음으로 고안되었지만, 우리는 1985년 토니 호어의 [이 논문][paper]에 실린 것이 가볍게 적용된 버전을 사용할 것입니다.

[paper]: http://www.usingcsp.com/cspbook.pdf


> 고대, 어떤 부유한 자선사업가가 다섯 명의 저명한 철학가를 모실 수 있도록 한 대학을 후원했습니다.
> 각각의 철학자들은 그들이 그들의 전문적인 사고에 몰입할 수 있는 방을 하나씩 얻었죠. 그리고 공동으로
> 사용하는 식당이 하나 있었는데, 그 식당에는 각 철학자들의 이름이 새겨진 다섯 의자로 둘러쌓인
> 원형 식탁이 있었습니다. 철학자들은 이 식닥을 둘러싸고 반시계 방향으로 앉았습니다. 각 철학자의
> 왼쪽에는 금으로 된 포크가 하나씩 놓여 있었고, 식탁의 중앙에는 계속해서 채워지는, 스파게티가
> 가득 담긴 쟁반이 놓여 있었죠. 대학에서는 철학자라는 이들은 어차피 대부분의 시간을 그저
> 생각하는데에 사용했습니다. 하지만, 배고픔을 느낄 때에는 중앙의 식당으로 와서, 자기 이름이
> 쓰인 의자에 앉은 뒤에, 그의 왼쪽에 놓인 그의 포크를 집어들고, 스파게티에 그걸 내리꽂았죠.
> 하지만 스파게티란게 워낙에 꼬여 있는 음식인지라, 스파게티를 입으로 옮기기 위해서는 포크가
> 하나 더 필요했어요. 따라서 그 철학자는 그의 오른쪽에 놓인 포크를 집어들어야만 했죠. 배를
> 채운 뒤, 그 철학자는 양 손에 든 포크를 내려놓고, 의자에서 일어나, 다시 생각을 이어가겠죠.
> 당연히 하나의 포크는 한 번에 한 명만 사용 가능합니다. 만약 다른 철학자가 현재 사용중인
> 포크를 필요로 한다면, 지금 그 포크를 사용중인 철학자가 식사를 끝낼 때까지 기다려야해요.

이 고전적인 문제는 동시성의 몇 가지 요소들을 보여줍니다. 사실 이 문제를 구현하는 것은 좀 까다로운데, 단순하게 생각하고 구현했다가는 데드락이 발생할 수 있습니다. 예를 들어, 이 문제를 해결하기 위한 아래와 같은 단순한 알고리즘을 생각해봅시다.

1. 철학자가 자신의 왼쪽에 놓인 포크를 집어든다.
2. 그 다음엔 자기 오른쪽에 놓인 포크를 집어든다.
3. 먹는다.
4. 포크를 반납한다.

이제, 다음과 같은 일련의 사건들을 상상해보세요:

1. 철학자 1이 알고리즘을 시작하고, 자기 왼쪽에 놓인 포크를 집어듭니다.
2. 철학자 2가 알고리즘을 시작하고, 자기 왼쪽에 놓인 포크를 집어듭니다.
3. 철학자 3이 알고리즘을 시작하고, 자기 왼쪽에 놓인 포크를 집어듭니다.
4. 철학자 4가 알고리즘을 시작하고, 자기 왼쪽에 놓인 포크를 집어듭니다.
5. 철학자 5가 알고리즘을 시작하고, 자기 왼쪽에 놓인 포크를 집어듭니다.
6. ...?
모든 포크는 사용중이지만, 아무도 먹을 수 없죠!

이 문제를 해결 할 수 있는 여러가지 방법이 있습니다. 이 튜토리얼 내에서 우리도 우리의 해결책을 찾아낼 거에요. 일단 지금 당장은, 문제 자체부터 모델링해보죠. 철학자들부터 시작합시다.

```rust
struct Philosopher {
name: String,
}

impl Philosopher {
fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
}
}

fn main() {
let p1 = Philosopher::new("Judith Butler");
let p2 = Philosopher::new("Gilles Deleuze");
let p3 = Philosopher::new("Karl Marx");
let p4 = Philosopher::new("Emma Goldman");
let p5 = Philosopher::new("Michel Foucault");
}
```

여기서, 우리는 철학자를 나타내기 위해 [`struct`][struct]를 만들었습니다. 지금으로서는, 이름이 우리가 필요로 하는 전부죠. 이름을 나타내기 위해서 `&str`이 아니라 [`String`][string] 타입을 선택했습니다. 일반적으로, 실제 값에 대한 주소를 갖고 있는 참조를 사용하는 것보다는 그 자신이 값을 들고 있는 타입을 쓰는 게 수월합니다.

[struct]: structs.html
[string]: strings.html

계속 해 봅시다.

```rust
# struct Philosopher {
# name: String,
# }
impl Philosopher {
fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
}
}
```

이 `impl` 블락을 통해 우리는 `Philosopher` 구조체 내에 여러가지를 정의할 수 있습니다. 이 경우, `new`라고 불리는, 연관된 함수를 정의했죠. 첫 라인은 다음과 같습니다.

```rust
# struct Philosopher {
# name: String,
# }
# impl Philosopher {
fn new(name: &str) -> Philosopher {
# Philosopher {
# name: name.to_string(),
# }
# }
# }
```

여기서 우리는 `&str` 타입을 갖는 `name`이라는 인자 하나를 받죠. 이 인자는 다른 문자열에 대한 참조입니다. 그리고 `Philosopher` 구조체 인스턴스를 리턴합니다.

```rust
# struct Philosopher {
# name: String,
# }
# impl Philosopher {
# fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
# }
# }
```

이 함수는 새로운 `Philosopher`를 생성하고, 그것의 `name`을 우리의 `name`인자로 설정합니다. 다만, 인자 그 자체가 아닌, 인자에 `.to_string()`을 호출한 것을 말이죠. 이 함수는 우리의 `&str`가 가리키고 있는 문자열의 복사본을 생성하고, 우리에게 새로 만들어진 `String`을 줍니다. `Philsopher`의 `name` 필드의 타입과 같죠.

왜 직접 `String`을 받지 않을까요? 호출의 용이성 때문입니다. 만약 우리가 `String`을 받지만, 호출자는 `&str`를 갖고 있다면, 호출자가 직접 `.to_string()`을 호출해야 할 것입니다. 이러한 유연성의 단점은 우리가 _항상_ 복사본을 만든다는 것입니다. 이것과 같이 조그마한 프로그램에 대해서는, 어차피 우리가 짧은 문자열만 사용할 것을 알기 때문에 그렇게 큰 문제는 아니지만요.

마지막으로 주목하셔야 할 것이 하나 있습니다. 우리는 `Philosopher`를 정의했지만, 그걸로 아무 일도 하지 않는 것처럼 보입니다. Rust는 '표현 기반' 언어입니다. 이는 Rust에서는 거의 모든 것이 어떤 값을 리턴하는 표현식임을 의미하죠. 이는 함수에도 마찬가지로 적용되는데, 함수의 마지막 표현식이 자동으로 리턴됩니다. 우리가 이 함수의 마지막 표현식에서 새로운 `Philosopher`를 생성했기 때문에, 이 함수는 그것을 리턴합니다.

이 함수의 이름인 `new()`는 Rust에게는 아무런 특별한 의미를 갖지 않지만, 구조체의 새로운 인스턴스를 생성하는 함수들에 관습적으로 사용됩니다. 왜인지 이야기하기 전에, `main()` 함수를 다시 살펴보죠.


```rust
# struct Philosopher {
# name: String,
# }
#
# impl Philosopher {
# fn new(name: &str) -> Philosopher {
# Philosopher {
# name: name.to_string(),
# }
# }
# }
#
fn main() {
let p1 = Philosopher::new("Judith Butler");
let p2 = Philosopher::new("Gilles Deleuze");
let p3 = Philosopher::new("Karl Marx");
let p4 = Philosopher::new("Emma Goldman");
let p5 = Philosopher::new("Michel Foucault");
}
```

여기서, 우리는 다섯 명의 철학자들을 이용해 다섯 개의 변수 바인딩을 생성했습니다. 이 사람들은 제가 가장 좋아하는 다섯 명인데, 여러분은 여러분이 원하는 분으로 바꾸셔도 상관 없습니다. 만약 우리가 `new()` 함수를 정의하지 _않았다면_, 다음과 같이 작성해야 했겠죠.

```rust
# struct Philosopher {
# name: String,
# }
fn main() {
let p1 = Philosopher { name: "Judith Butler".to_string() };
let p2 = Philosopher { name: "Gilles Deleuze".to_string() };
let p3 = Philosopher { name: "Karl Marx".to_string() };
let p4 = Philosopher { name: "Emma Goldman".to_string() };
let p5 = Philosopher { name: "Michel Foucault".to_string() };
}
```

훨씬 부산스럽죠? `new`를 사용하는 것은 다른 여러 장점들도 가지고 있지만, 이렇게 간단한 경우에조차, 코드를 작성하기가 훨씬 편리해집니다.

이제 기초적인 내용들을 알았으니, 이 문제에 도전해 볼 수 있는 여러가지 방법들이 존재합니다. 끝 부분부터 작성해 볼까요? 각각의 철학자들이 식사를 마칠 수 있는 방법을 마련해봅시다. 작은 발걸음부터 떼는 의미에서, 메소드 하나를 생성하고, 모든 철학자를 돌면서 그 메소드를 호출해봅시다.

```rust
struct Philosopher {
name: String,
}

impl Philosopher {
fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
}

fn eat(&self) {
println!("{} is done eating.", self.name);
}
}

fn main() {
let philosophers = vec![
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];

for p in &philosophers {
p.eat();
}
}
```

`main()` 함수를 먼저 살펴보죠. 다섯 철학자들을 위해 5개의 변수 바인딩을 각각 만드는 대신, 그들의 `Vec`를 만들어 봅시다. `Vec`는 '벡터'라고도 불리우는데, 성장 가능한 배열 타입이에요. 그 뒤에는 [`for` 반복문][for]을 이용해서 벡터 내를 순회하며 차례로 각각의 철학자들을 가리키는 참조를 얻어옵니다.

[for]: for-loops.html

반복문의 몸체에서, 우리는 위에서 정의한 `p.eat()`을 호출합니다.

```
rust,ignore
fn eat(&self) {
println!("{} is done eating.", self.name);
}
```

Rust에서, 메소드는 명시적인 `self` 파라미터를 받습니다. 그게 `eat()`은 메소드이지만 `new`는 연관된 함수인 이유인데요. `new()`는 `self`를 갖지 않죠. 우리의 초기 버전 `eat()`에서 우리는 그냥 철학자의 이름을 출력한 뒤 그가 식사를 끝냈다고 언급합니다. 이 프로그램을 돌리면 다음과 같은 결과를 얻게 되겠죠.

```text
Judith Butler is done eating.
Gilles Deleuze is done eating.
Karl Marx is done eating.
Emma Goldman is done eating.
Michel Foucault is done eating.
```

어렵지 않죠? 모두가 식사를 마쳤군요! 하지만 우리는 실제 문제를 구현하지 않았으므로, 우리는 아직 갈 길이 많이 남았습니다.

다음으로, 우리는 철학자들이 식사를 마치기만 하는게 아니라, 실제로 식사를 하길 원합니다. 다음 버전은 이렇게 생겼어요.

```rust
use std::thread;

struct Philosopher {
name: String,
}

impl Philosopher {
fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
}

fn eat(&self) {
println!("{} is eating.", self.name);

thread::sleep_ms(1000);

println!("{} is done eating.", self.name);
}
}

fn main() {
let philosophers = vec![
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];

for p in &philosophers {
p.eat();
}
}
```

몇 가지 변화가 있었죠. 쪼개서 살펴봅시다.

```
rust, ignore
use std::thread;
```

`use`는 이름을 유효 범위 내로 끌어들입니다. 우리는 표준 라이브러리에 있는 `thread` 모듈을 사용하기 시작할거고, 따라서 그 모듈을 `use` 해야하죠.

```
rust,ignore
fn eat(&self) {
println!("{} is eating.", self.name);

thread::sleep_ms(1000);

println!("{} is done eating.", self.name);
}
```

이제 우리는 두 메세지를 출력하는데, 그 사이에 `sleep_ms()`가 있네요. 이 함수는 철학자가 식사를 하는데 걸리는 시간을 시뮬레이트합니다.

이 프로그램을 실행시키면, 각각의 철학자가 차례로 식사를 하는 것을 볼 수 있을 것입니다.

```text
Judith Butler is eating.
Judith Butler is done eating.
Gilles Deleuze is eating.
Gilles Deleuze is done eating.
Karl Marx is eating.
Karl Marx is done eating.
Emma Goldman is eating.
Emma Goldman is done eating.
Michel Foucault is eating.
Michel Foucault is done eating.
```

훌륭하군요! 점점 목표에 가까워지고 있습니다. 다만 문제가 하나 있는데, 우리는 지금 동시성을 고려하는 방식으로 작업하지 않고 있죠. 동시성은 이 문제의 핵심인데 말이에요!

철학자들이 동시적으로 식사하도록 만들기 위해, 작은 변화를 만들 필요가 있습니다.
다음 버전입니다.

```rust
use std::thread;

struct Philosopher {
name: String,
}

impl Philosopher {
fn new(name: &str) -> Philosopher {
Philosopher {
name: name.to_string(),
}
}

fn eat(&self) {
println!("{} is eating.", self.name);

thread::sleep_ms(1000);

println!("{} is done eating.", self.name);
}
}

fn main() {
let philosophers = vec![
Philosopher::new("Judith Butler"),
Philosopher::new("Gilles Deleuze"),
Philosopher::new("Karl Marx"),
Philosopher::new("Emma Goldman"),
Philosopher::new("Michel Foucault"),
];

let handles: Vec<_> = philosophers.into_iter().map(|p| {
thread::spawn(move || {
p.eat();
})
}).collect();

for h in handles {
h.join().unwrap();
}
}
```

우리가 한 일이라곤 `main()`내의 반복문을 약간 바꾸고, 두 번째 반복문을 추가한 것 뿐이에요! 첫 번째 변화는 다음과 같습니다.

```
rust,ignore
let handles: Vec<_> = philosophers.into_iter().map(|p| {
thread::spawn(move || {
p.eat();
})
}).collect();
```

위의 코드는 다섯 줄 밖에 안 되지만, 이 다섯 줄은 매우 밀도 있는 라인입니다.
하나씩 살펴보죠.

```
rust,ignore
let handles: Vec<_> =
```

여기서, `handles`라는 이름을 갖는 새로운 바인딩이 등장합니다. 이러한 이름을 준 이유는 우리가 새로운 쓰레드들을 생성할거고, 이 때 그 쓰레드들의 동작을 제어할 수 있는 핸들이 리턴될 것이기 때문이에요. 좀 더 나중에 이야기할 이유 때문에, 여기서는 명시적으로 타입을 기술해주어야 합니다. `_`는 타입 플레이스홀더입니다. 우리는 "`handles`는 무언가의 벡터인데, 그 무언가가 뭐인지는 Rust 네가 알아맞춰보렴" 이라고 말하고 있는거에요.

```
rust,ignore
philosophers.into_iter().map(|p| {
```

우리는 철학자의 리스트를 받은 뒤에 거기에다가 `into_iter()`를 호출합니다. 이를 통해 철학자 각각의 소유권을 갖는 반복자가 반환됩니다. 우리는 각각의 소유권을 쓰레드들에 전달하기 위해 이러한 일을 하는데요. 그 반복자에 `map`을 호출하는데, `map`은 인자로 클로저를 받고 각각의 원소들에 그 클로저를 차례로 호출합니다.

```
rust,ignore
thread::spawn(move || {
p.eat();
})
```

여기가 동시성이 일어나는 지점입니다. `thread::spawn` 함수는 인자로 클로저를 받고 새로운 스레드에서 그 클로저 구문을 실행합니다. 이 클로저는 전에 가지고 왔던 값들의 소유권을 받아오기 위해 `move`라는 특별한 명시가 필요합니다. 주로 `map` 함수의 `p` 값들을 말이죠.

스레드 내부에서 우리는 단지 `p`의 `eat()`을 호출하는 일이 전부입니다. 또한 `thread::spawn`함수는 표현식을 만들기 때문에, 끝에 지긋지긋한 `;`이 없는 것에 주목하세요. 이 구분이 중요한 이유는 올바른 반환 값을 넘겨줘야하기 때문입니다. 더 상세한 정보는, [Expressions vs. Statements][es]를 읽어보세요.

[es]: functions.html#expressions-vs.-statements

```rust,ignore
}).collect();
```

마지막으로, `map` 호출의 결과를 받아 그들을 모아야 합니다. `collect()`함수는 이들을 어떤 종류의 모음(collection)으로 만드는데, 이 때문에 우리가 리턴 타입을 명시해줘야 했던 것입니다: `Vec` 타입으로 원해요. 각 스레드들에서 처리를 했던 `thread::spawn` 호출의 반환 값들이 요소가 됩니다. 휴!

```rust,ignore
for h in handles {
h.join().unwrap();
}
```

`main()`의 끝에는 `handles`에 대해 루프를 돌며 각각 그것들에 `join()`을 호출합니다. 이것은 스레드가 작업을 완료할때까지 실행을 기다리게 됩니다. 따라서 프로그램이 끝나기 전에 스레드가 작업을 완료한다는 것을 보증할 수 있습니다.

프로그램을 실행해보면, 철학자들이 음식을 마구 먹고 있습니다!
멀티스레딩을 한 것입니다!

```text
Judith Butler is eating.
Gilles Deleuze is eating.
Gilles Deleuze is done eating.
Emma Goldman
Karl Marx is eating.
Emma Goldman is done eating.
Michel Foucault is eating.
Judith Butler is eating.
Judith Butler is done eating.
Gilles Deleuze is done eating.
Karl Marx is done eating.
Karl MarxEmma Goldman is done eating.
Michel Foucault is done eating.
```

그런데 포크는 어쨌을까요? 우리는 아직 구현하지 않았습니다.

새로 `struct`를 만듭시다:

```rust
use std::sync::Mutex;

struct Table {
forks: Vec>,
}
```
이 `Table`은 `Mutex`들의 벡터를 가지고 있습니다. 뮤텍스는 동시성을 제어하는 방법 중 하나입니다: 한번에 오직 한 스레드만이 내부에 접근할 수 있습니다. 우리의 포크를 만드는데 딱 필요한 성질입니다. 실제로 값을 쓰지는 않고 그저 들고 있기만 하면 되기 때문에, 빈 튜플인 `()`를 뮤텍스 안에 사용했습니다.

`Table`을 사용할 프로그램을 수정해봅시다:

```rust
use std::thread;
use std::sync::{Mutex, Arc};

struct Philosopher {
name: String,
left: usize,
right: usize,
}

impl Philosopher {
fn new(name: &str, left: usize, right: usize) -> Philosopher {
Philosopher {
name: name.to_string(),
left: left,
right: right,
}
}

fn eat(&self, table: &Table) {
let _left = table.forks[self.left].lock().unwrap();
let _right = table.forks[self.right].lock().unwrap();

println!("{} is eating.", self.name);

thread::sleep_ms(1000);

println!("{} is done eating.", self.name);
}
}

struct Table {
forks: Vec>,
}

fn main() {
let table = Arc::new(Table { forks: vec![
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
]});

let philosophers = vec![
Philosopher::new("Judith Butler", 0, 1),
Philosopher::new("Gilles Deleuze", 1, 2),
Philosopher::new("Karl Marx", 2, 3),
Philosopher::new("Emma Goldman", 3, 4),
Philosopher::new("Michel Foucault", 0, 4),
];

let handles: Vec<_> = philosophers.into_iter().map(|p| {
let table = table.clone();

thread::spawn(move || {
p.eat(&table);
})
}).collect();

for h in handles {
h.join().unwrap();
}
}
```

많이 바뀌었군요! 하지만 많은 요소가 반복되어서, 프로그램을 이해할 수 있습니다.
자세하게 들어가보죠:

```rust,ignore
use std::sync::{Mutex, Arc};
```

`std::sync` 패키지에 있는 `Arc`를 쓰려고 합니다. 실제 사용할 때 자세히 얘기하죠.

```rust,ignore
struct Philosopher {
name: String,
left: usize,
right: usize,
}
```

`Philosopher`에 2개의 필드를 추가했습니다. 각 철학자들은 2개의 포크를 가집니다: 하나는 왼쪽, 하나는 오른쪽. `usize`타입은 벡터 인덱스(e.g. Vec[index]) 타입입니다. 이 두 값은 `Table`이 가진 `forks`의 인덱스가 될 것입니다.

```rust,ignore
fn new(name: &str, left: usize, right: usize) -> Philosopher {
Philosopher {
name: name.to_string(),
left: left,
right: right,
}
}
```

`new()`에서 `left`와 `right`값을 설정해줄 필요가 있습니다.

```rust,ignore
fn eat(&self, table: &Table) {
let _left = table.forks[self.left].lock().unwrap();
let _right = table.forks[self.right].lock().unwrap();

println!("{} is eating.", self.name);

thread::sleep_ms(1000);

println!("{} is done eating.", self.name);
}
```

`table`을 인자로 받는 것과 두 줄이 추가되었습니다. `Table`의 forks 리스트에서 `self.left`와 `self.right`로 특정 인덱스들에 접근할 수 있습니다. 그렇게 함으로써 그 인덱스들의 `Mutex`에 접근할 수 있고 `lock()`을 호출할 수 있습니다. 만약 해당 뮤텍스가 현재 누군가에게 접근되었다면, 다시 사용가능할때까지 잠급니다.

`lock()`호출은 종종 실패하는데, 그 경우 충돌이 일어납니다. 이 오류는 뮤텍스가 [‘poisoned’][poison]일때 일어날 수 있습니다. [‘poisoned’][poison]는 잠겨 있는 도중에 스레드가 패닉(panic)할 때 일어납니다. 이러한 일은 일어나선 안되므로, `unwrap()`을 사용해줍니다.

[poison]: ../std/sync/struct.Mutex.html#poisoning

그 두줄에 이상한 것이 또 있습니다: 결과에 `_left`와 `_right`라 이름붙였습니다. 이 밑줄은 뭔가요? 음, 우리는 잠긴 값을 _사용할(using)_ 예정이 없습니다. 우리는 단지 값을 얻어오면 됩니다. 그래서, 러스트는 이 값들이 사용되지 않았다고 경고할 것입니다. 밑줄을 사용하면, 러스트에게 '이건 일부러 그런거야'라고 알려주고, 경고를 내뱉지 않을 겁니다.

그런데 잠금 해제는 어떻게 하나요? 호, `_left`와 `_right`가 스코프 밖으로 나가면 자동적으로 이루어집니다.

```rust,ignore
let table = Arc::new(Table { forks: vec![
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
Mutex::new(()),
]});
```
다음으로 `main()`에서, 새로운 `Table`을 만들고 `Arc`로 감쌉니다. 'arc'는 '원자적 참조 카운트(atomic reference count)를 나타냅니다. 다수의 스레드에서 우리의 `Table`을 나눌 필요가 있습니다. 우리가 그것을 나누면 참조 카운트가 올라가고, 각 스레드가 끝나면 다시 내려갑니다.


```rust,ignore
let philosophers = vec![
Philosopher::new("Judith Butler", 0, 1),
Philosopher::new("Gilles Deleuze", 1, 2),
Philosopher::new("Karl Marx", 2, 3),
Philosopher::new("Emma Goldman", 3, 4),
Philosopher::new("Michel Foucault", 0, 4),
];
```
`Philosopher`를 생성할 때, 생성자에게 `left`와 `right` 값을 넘겨주어야 합니다. 한 가지 더 자세하고 _매우_ 중요한 것이 있습니다. 패턴을 잘 살펴보면, 끝에 이르기전까진 일정합니다. 그런데 Michel Foucault가 `0, 4`로 되어있습니다. `4, 0`이 아니라요. 사실 이것이 데드락을 막아줍니다: 우리의 철학자들 중 한 명은 왼손잡이라는 것 말입니다! 저는 이 방법이 문제를 해결하는 가장 간단한 해법 중 하나라고 생각합니다.

```rust,ignore
let handles: Vec<_> = philosophers.into_iter().map(|p| {
let table = table.clone();

thread::spawn(move || {
p.eat(&table);
})
}).collect();
```

마지막으로, `map()`/`collect()` 루프를 사용하는 대신, `table.clone()`을 호출했습니다. `clone()`함수는 `Arc`에 있는 메소드로써 참조 카운트를 올리고, 그것이 스코프 밖으로 나가면 카운트를 줄입니다. 스레드들을 넘어서 `table`에 참조가 얼마나 되었는지 알기 위해서 필요합니다. 만약 이러한 카운트가 없다면, 그것을 어떻게 해제(deallocate)해야할지 알 수 없을 겁니다.

아마 당신은 기존의 이름을 갱신하는 `table`의 새로운 바인딩 방식에 대해 눈치채셨을지도 모르겠습니다. 딱히 또 다른 새로운 이름을 만들 필요가 없을 때 사용합니다.

이것들로, 프로그램이 완성되었습니다! 오직 두 철학자만이 한번에 음식을 먹을 수 있고, 다음과 같은 결과를 볼 수 있습니다:

```text
Gilles Deleuze is eating.
Emma Goldman is eating.
Emma Goldman is done eating.
Gilles Deleuze is done eating.
Judith Butler is eating.
Karl Marx is eating.
Judith Butler is done eating.
Michel Foucault is eating.
Karl Marx is done eating.
Michel Foucault is done eating.
```

축하합니다! 당신은 러스트를 통해 고전적인 동시성 문제를 해결했습니다.
documentation
# 4.4. 문서화 (Documentation) - 20%

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

이 [불행한 오류](https://github.com/rust-lang/rust/issues/22547)는 맞습니다. documentation comments apply to the thing after them, and there's no
thing after that last comment
정상적인 동작입니다. 문서 처리를 수행하면 그 뒤에 따라오는 글들을 모두 주석으로 처리하며, 주석 뒤에는 아무것도 없는 것으로 인식합니다.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

여러분의 함수가 `unsafe`라면, you should explain which invariants the caller is
responsible for upholding.

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

ThirdFourth, `Examples`. Include one or more examples of using your function or
method, and your users will love you for it. These examples go inside of
code block annotations, which we'll talk about in a moment, and can have
more than one section:
함수나 method를 사용하기 위한 하나 이상의 예제를 추가하는 것이 사용자에게 큰 도움이 될 것입니다. 이 예제들은 곧 다시 언급할 코드 블록 주석에 포함될 것이며, 그 때 더 자세하게 설명될 것입니다.

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

Let's discuss the details of these code blocks위 코드 블록 주석들에 대해 더 자세하게 알아보도록 하겠습니다.

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

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

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

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

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

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

`rustdoc`이 이것을 사용에서 이 항목을 인식하기 때문에, 정확한 언어를 선택하는 것은 중요합니다. It can be used to actually test your examples, so that they don't get out of date. If you have some C code but `rustdoc` thinks it's Rust because you left off the annotation, `rustdoc` will complain when trying to
generate the documentation
적합한 값을 적용했는지 확인하기 위해 실제로 당신의 예제를 테스트하는 데 사용되기도 합니다. 만약 당신이 C code를 사용하고 이 부분을 비워놓았다면 `rustdoc`은 예제를 Rust 코드로 인식하며, 문서화 작업 중 이에 대한 complain이 발생할 것입니다.

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

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

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

You'll notice that you don't need a `fn main()` or anything here. `rustdoc` will
automatically add a main() wrapper around your code, and in the right place.
For example:

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

This will end up testing:

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

Here's the full algorithm rustdoc uses to postprocess examples:

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

Sometimes, this isn't enough, though. For example, all of these code samples
with `///` we've been talking about? The raw text:

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

looks different than the output:

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

Yes, that's right: you can add lines that start with `# `, and they will
be hidden from the output, but will be used when compiling your code. You
can use this to your advantage. In this case, documentation comments need
to apply to some kind of function, so if I want to show you just a
documentation comment, I need to add a little function definition below
it. At the same time, it's just there to satisfy the compiler, so hiding
it makes the example more clear. You can use this technique to explain
longer examples in detail, while still preserving the testability of your
documentation. For example, this code:

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

Here's an explanation, rendered:

First, we set `x` to five:

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

Next, we set `y` to six:

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

Finally, we print the sum of `x` and `y`:

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

Here's the same explanation, in raw text:

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

By repeating all parts of the example, you can ensure that your example still
compiles, while only showing the parts that are relevant to that part of your
explanation.

### Documenting macros

Here’s an example of documenting a macro:

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

You’ll note three things: we need to add our own `extern crate` line, so that
we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
`main()` as well. Finally, a judicious use of `#` to comment out those two
things, so they don’t show up in the output.

### Running documentation tests

To run the tests, either

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

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

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

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

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

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

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

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

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

### Documenting modules

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

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

// ...
}
```

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

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

### Documentation comment style

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

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

## Other documentation

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

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

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

is just

~~~markdown
# Examples

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

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

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

```markdown
% The title

This is the example documentation.
```

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

## `doc` attributes

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

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

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

are the same, as are these:

```rust
//! this

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

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

### Re-exports

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

```ignore
extern crate foo;

pub use foo::bar;
```

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

This behavior can be suppressed with `no_inline`:

```ignore
extern crate foo;

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

### Controlling HTML

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

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

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

## Generation options

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

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

## Security note

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

```rust
///
# fn foo() {}
```
error-handling
# 4.7. 오류 처리 (Error Handling) - 99%

> The best-laid plans of mice and men
> Often go awry
>
> "Tae a Moose", Robert Burns

때때로, 일은 잘못 굴러갑니다. 불가피한 것들이 일어날때를 위한 계획을
가지는 것은 중요합니다. Rust는 당신의 프로그램에서 일어날 지도 모르는
(우리 솔직해지죠. 반드시 일어납니다.) 에러들을 처리하기 위한 풍부한 지원 방법들을
가지고 있습니다.

당신의 프로그램에서 일어날 수 있는 주된 에러들은 두가지 종류가 있습니다: 실패(failure)와 패닉(panic)입니다. 두가지의 차이점에 대해 말해보고, 각각을 어떻게 처리할지 논의해 봅시다. 그런다음, 실패를 패닉으로 업그레이드 하는 것에 대해 논의할 것입니다.

# 실패 vs. 패닉

Rust는 두가지 유형의 에러를 구분하기 위해 두가지 용어를 씁니다: 실패(Failure),
그리고 패닉(Panic) 입니다. *실패*는 어떤 방법으로 복구될 수 있는 에러를 뜻합니다. *패닉*은 복구될 수 없는 에러를 뜻합니다.

'복구(recover)'의 뜻은 무엇일까요? 흠, 대부분의 경우에 에러의 가능성이 있습니다.
예를 들어, parse 함수를 고려해 봅시다.

```ignore
"5".parse();
```

이 메쏘드는 문자열을 다른 타입으로 변환합니다. 그러나 그것이 문자열이기 때문에,
당신은 변환이 실제로 일어날지를 확신할 수 없습니다. 예를 들어, 이것은 무엇으로
변환됩니까?

```ignore
"hello5world".parse();
```

이것은 동작하지 않습니다. 따라서 우리가 아는 것은, 이 함수가 단지 몇몇 입력에 대해서만
적절하게 작동한다는 겁니다. 이것은 예상된 동작입니다. 우리는 이러한 종류의 에러를 *실패*라고
합니다.

반면에, 때때로, 예상되지 않거나, 복구 불가능한 에러가 있습니다. 이에 대한
전통적인 예제는 `assert!`가 있습니다.

```rust
# let x = 5;
assert!(x == 5);
```

우리는 `assert!`를 무언가가 참이라고 선언하기 위해 사용합니다. 만약 그것이
참이 아니라면, 무언가가 대단히 잘못된 것입니다. 현재 상태에서 무언가를
계속할 수 없을 정도로 충분히 잘못된 겁니다. 다른 예제는 `unreachable!()`
매크로를 사용한 것입니다.

```rust,ignore
enum Event {
NewRelease,
}

fn probability(_: &Event) -> f64 {
// real implementation would be more complex, of course
0.95
}

fn descriptive_probability(event: Event) -> &'static str {
match probability(&event) {
1.00 => "certain",
0.00 => "impossible",
0.00 ... 0.25 => "very unlikely",
0.25 ... 0.50 => "unlikely",
0.50 ... 0.75 => "likely",
0.75 ... 1.00 => "very likely",
}
}

fn main() {
std::io::println(descriptive_probability(NewRelease));
}
```

이것은 다음과 같은 에러를 발생시킵니다.

```text
error: non-exhaustive patterns: `_` not covered [E0004]
```
우리는 위의 코드가 가능한 모든 경우를 다 다루고 있음을 알고 있지만, Rust는
그렇지 못합니다. Rust는 확률이 항상 0.0과 1.0 사이인 것을 알지 못합니다. 따라서
우리는 다른 경우에 대한 것을 추가해 주어야 합니다:

```rust
use Event::NewRelease;

enum Event {
NewRelease,
}

fn probability(_: &Event) -> f64 {
// real implementation would be more complex, of course
0.95
}

fn descriptive_probability(event: Event) -> &'static str {
match probability(&event) {
1.00 => "certain",
0.00 => "impossible",
0.00 ... 0.25 => "very unlikely",
0.25 ... 0.50 => "unlikely",
0.50 ... 0.75 => "likely",
0.75 ... 1.00 => "very likely",
_ => unreachable!()
}
}

fn main() {
println!("{}", descriptive_probability(NewRelease));
}
```

절대 `_`인 경우는 있을 수 없을 것이기에, 우리는 이것을 표시하기 위해
`unreachable!()` 매크로를 사용합니다. `unreachable!()`는 `Result`가 아닌 어떤
다른 종류의 에러를 줍니다. Rust는 이런 부류의 에러를 패닉(Panic)이라고 부릅니다.

# `Option`과 `Result`와 함께 에러 처리하기

어떤 함수가 실패할 지도 모른다는 것을 표시하는 가장 간단한 방법은 `Option`
타입을 사용하는 것입니다. 예를 들어, `find` 메쏘드는 문자열에서 패턴을 찾는 것을
시도하며, `Option`을 반환합니다:


```rust
let s = "foo";

assert_eq!(s.find('f'), Some(0));
assert_eq!(s.find('z'), None);
```

이것은 가장 단순한 경우에는 적합하지만, 실패한 경우에는 우리에게 충분한 정보를
제공하지 않습니다. 만약 우리가 왜 실패했는지를 알고 싶다면? 이것을 위해서는
우리는 `Result` 타입을 사용해야 합니다. 이 타입의 모습은 다음과 같습니다.

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

이 열거형은 러스트 그 자체에 의해 제공되며, 이걸 사용하기 위해 따로 정의할 필요는
없습니다. `Ok(T)` 변량(variant)은 성공을 나타내며, `Err(E)` 변량은 실패(failure)를 나타냅니다. `Option` 대신 `Result`를 리턴하는 것은 몇몇 사소한 상황을 제외한 거의 모든 경우에
권장됩니다.

여기에 `Result의 사용 예가 있습니다:

```rust
#[derive(Debug)]
enum Version { Version1, Version2 }

#[derive(Debug)]
enum ParseError { InvalidHeaderLength, InvalidVersion }

fn parse_version(header: &[u8]) -> Result {
if header.len() < 1 {
return Err(ParseError::InvalidHeaderLength);
}
match header[0] {
1 => Ok(Version::Version1),
2 => Ok(Version::Version2),
_ => Err(ParseError::InvalidVersion)
}
}

let version = parse_version(&[1, 2, 3, 4]);
match version {
Ok(v) => {
println!("working with version: {:?}", v);
}
Err(e) => {
println!("error parsing header: {:?}", e);
}
}
```

이 함수는 일어날 수 있는 다양한 에러들을 열거하기 위해
열거형 `ParseError`을 사용하고 있습니다.

[`Debug`](../std/fmt/trait.Debug.html) 트레이트는 `{:?}` 형식 연산을 이용해 열거값을 출력합니다.

# `panic!`을 통한 회복 불가능한 에러

예상할 수 없고 복구할 수 없는 에러에 관하여, `panic!` 매크로는 패닉을 유도합니다.
이것은 현재 쓰레드를 붕괴(crash)시키고, 에러를 줍니다.

```rust,ignore
panic!("boom");
```

위의 코드를 실행시키면

```text
thread '
' panicked at 'boom', hello.rs:2
```

위와 같은 에러가 발생합니다.

이런 경우는 상대적으로 드물기 때문에, 패닉은 삼가서 사용하세요.

# 실패(failure)를 패닉(panic)으로 업그레이드하기

특정 상황에서, 비록 함수가 단지 실패(Failure)를 일으킨다 하더라도,
우리는 이것을 패닉으로 간주하여 처리하고 싶을지도 모릅니다. 예를 들어,
`io::stdin().read_line(&mut buffer)`는 줄을 읽을때 에러가 발생하면 `Result`를
리턴합니다. 이것은 에러로부터 복귀하거나 에러를 처리하는 것을 가능하게 합니다.

그러나 이 에러를 처리하기를 원치 않고, 그냥 프로그램을 정지시키는 쪽을 원한다면,
우리는 `unwrap()` 메쏘드를 사용할 수 있습니다.

```rust,ignore
io::stdin().read_line(&mut buffer).unwrap();
```

`Result`가 `Err`인 경우에, `unwrap()`은 `panic!`을 일으킵니다. 이것은 기본적으로
`값을 줘, 그리고 뭔가 잘못 돌아간다면, 나는 가차없이 판을 뒤집을거야(crash)`라고
말하는 듯 합니다. 이런 방식은 에러를 매칭해서 복구를 시도하는 것보다 덜 유연한
방식이지만, 대신 현저하게 짧습니다. 때때로, 그냥 붕괴(crash)시키는 것이 적절하기도
합니다.

`unwrap()`보다 조금 더 멋진 방법도 있는데 다음과 같습니다:

```rust,ignore
let mut buffer = String::new();
let num_bytes_read = io::stdin().read_line(&mut buffer)
.ok()
.expect("Failed to read line");
```

`ok()`는 `Result`를 `Option`으로 바꾸며, `expect()`는 `unwrap()`과 같은 일을 하지만,
메시지를 취한다는 점이 약간 다릅니다. 이 메시지는 그 밑에 있는 `panic!`까지
전달될 것이며, 코드에 오류가 발생하는 경우에 좀 더 나은 에러 메시지를
제공할 것입니다.

# `try!`의 사용

`Result` 타입을 반환하는 함수들을 많이 호출하는 코드를 작성할 때, 에러 처리는 지루할 수 있습니다. `try!` 매크로는 호출 스택의 상위로 전달되는 판에 박힌 에러의 일부분을 숨깁니다.

아래의 코드는:

```rust
use std::fs::File;
use std::io;
use std::io::prelude::*;

struct Info {
name: String,
age: i32,
rating: i32,
}

fn write_info(info: &Info) -> io::Result<()> {
let mut file = File::create("my_best_friends.txt").unwrap();

if let Err(e) = writeln!(&mut file, "name: {}", info.name) {
return Err(e)
}
if let Err(e) = writeln!(&mut file, "age: {}", info.age) {
return Err(e)
}
if let Err(e) = writeln!(&mut file, "rating: {}", info.rating) {
return Err(e)
}

return Ok(());
}
```

이렇게 대체될 수 있습니다:

```rust
use std::fs::File;
use std::io;
use std::io::prelude::*;

struct Info {
name: String,
age: i32,
rating: i32,
}

fn write_info(info: &Info) -> io::Result<()> {
let mut file = File::create("my_best_friends.txt").unwrap();

try!(writeln!(&mut file, "name: {}", info.name));
try!(writeln!(&mut file, "age: {}", info.age));
try!(writeln!(&mut file, "rating: {}", info.rating));

return Ok(());
}
```

`try!`로 둘러싸인 수식은 그 결과가 `Err`이 아닌 이상 둘러쌓이지 않은
성공(`OK`)값을 반환하게 됩니다. 그 결과가 `Err`인 경우에는 안쪽 둘러싸인
함수에서 넘겨받은 `Err`을 반환하게 됩니다.

이것은 `Result`를 리턴하는 함수에 대해 `try!`를 사용할때에만 유용한데, 이것은
아무것도 반환하지 않는 `main()`함수의 안에서는 `try!`를 사용할 수 없음을 의미합니다.

`try!`은 에러가 발생한 경우에, 무엇을 반환할지를 결정하기 위해 [`From`](../std/convert/trait.From.html)을 이용합니다.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.

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` 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-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 '
' 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 {
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 {
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(value: T) -> Option`. Correspondingly, `None` is also a
value constructor, except it has no arguments. You can think of `None` as a
function with the type `fn() -> Option`.

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 { 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` returned by the `find` function. In fact, case
analysis is the only way to get at the value stored inside an `Option`. This
means that you, as the programmer, must handle the case when an `Option` 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 {
None,
Some(T),
}

impl Option {
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` 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`. 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 { 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`, 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(option: Option, f: F) -> Option where F: FnOnce(T) -> A {
match option {
None => None,
Some(value) => Some(f(value)),
}
}
```

Indeed, `map` is [defined as a method][2] on `Option` 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 { 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`:

```rust
fn unwrap_or(option: Option, 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`. Using it is dead simple in our case:

```rust
# fn find(haystack: &str, needle: char) -> Option {
# 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` 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(option: Option, f: F) -> Option

where F: FnOnce(T) -> Option
{
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` is `None`.

## The `Result` type

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

```rust
enum Result {
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` in every way:

```rust
type Option = Result;
```

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 { Ok(T), Err(E) }
impl Result {
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::().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 '
' 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(&self) -> Result;
}
```

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 {
match number_str.parse::() {
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 {
number_str.parse::().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`. 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 = result::Result;

fn double_number(number_str: &str) -> Result {
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`, 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` or a `Result`. But what happens when you have both an
`Option` and a `Result`? Or what if you have a `Result` and a
`Result`? 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 {
argv.nth(1)
.ok_or("Please give at least one argument".to_owned())
.and_then(|arg| arg.parse::().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(option: Option, err: E) -> Result {
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` (from `argv.nth(1)`) to a `Result`, 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>(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` 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`. 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>(file_path: P) -> Result {
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::()
.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`, 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>(file_path: P) -> Result {
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>(file_path: P) -> Result {
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::().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>(file_path: P) -> Result {
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` 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 {
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 = From::from("foo");
let cow: ::std::borrow::Cow = 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 for Box
```

This impl says that for *any* type that impls `Error`, we can convert it to a
trait object `Box`. 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::().unwrap_err();

// OK, here are the conversions.
let err1: Box = From::from(io_err);
let err2: Box = 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>(file_path: P) -> Result {
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::().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`:

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

fn file_double>(file_path: P) -> Result> {
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::());
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` type is *opaque*. If we
return a `Box` 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` 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`, 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>(file_path: P) -> Result {
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 for CliError {
fn from(err: io::Error) -> CliError {
CliError::Io(err)
}
}

impl From 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 for CliError {
# fn from(err: io::Error) -> CliError { CliError::Io(err) }
# }
# impl From 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>(file_path: P) -> Result {
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 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 "]

[[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] ", program)));
}

fn main() {
let args: Vec = 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,
latitude: Option,
longitude: Option,
}

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

fn main() {
let args: Vec = 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::() {
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`. Later, we'll see how defining our own
error type can be useful.

## Error handling with `Box`

`Box` 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` 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`. In
this case, `OurErrorType` is just `Box`. 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`. (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] ", program)));
}

fn search>(file_path: P, city: &str) -> Vec {
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::() {
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 = 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,
Box>`.
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>
(file_path: P, city: &str)
-> Result, Box> {
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::() {
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`, the `try!` macro will return early from the function if an
error occurs.

There is one big gotcha in this code: we used `Box`
instead of `Box`. 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

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

Now that we've seen how to do proper error handling with `Box`, 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] ", 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`), and convert it to a type that `search` can use, in
this case, `&Option>`. Do do this, we take a reference of
file, and map `Path::new` onto it. In this case, `as_ref()` converts
the `Option` 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>
(file_path: &Option

, city: &str)
-> Result, Box> {
let mut found = vec![];
let input: Box = 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 for CliError {
fn from(err: io::Error) -> CliError {
CliError::Io(err)
}
}

impl From 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>
(file_path: &Option

, city: &str)
-> Result, CliError> {
let mut found = vec![];
let input: Box = 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::() {
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`, 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`, 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` for your
error type (the `Box` 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

# 4.89. 외부 함수 인터페이스 (Foreign Function Interface) - 650%

# Introduction

여기서는 외부 코드를 바인딩하기 위해서 [snappy](https://github.com/google/snappy)라는 압축/해제 라이브러리를 사용할 것입니다. 러스트는 현재 C++ 라이브러리를 직접 호출할 수는 없지만, snappy에는 C 인터페이스를 포함하고 있기 때문에 문제 없습니다. (문서 [`snappy-c.h`](https://github.com/google/snappy/blob/master/snappy-c.h)).

snappy를 설치했다면 다음과 같이 작은 예제를 작성해 외부 함수를 불러봅시다:

```no_run
# #![feature(libc)]
extern crate libc;
use libc::size_t;

#[link(name = "snappy")]
extern {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}

fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println!("max compressed length of a 100 byte buffer: {}", x);
}
```

`extern`키워드의 `{}`에 외부 라이브러리 안에 있는 함수들을 나열하며, 우리는 C ABI 플랫폼을 사용중입니다. `#[link(...)]` 속성은 링커에게 snappy 라이브러리를 링크하라고 지시할 때 사용하며, 심볼이 결합되어있습니다.

외부 함수는 불안정하다고 간주되기 때문에 컴파일러에게 이 함수들은 괜찮다고 알려주려면 `unsafe {}`로 감싸주어야 합니다. C 라이브러리는 보통 인터페이스를 노출하며 스레드-안전하지 않고 대부분의 함수가 유효하지 못한 포인터를 인자로 받아 댕글링 포인터가 될 수 있는 위험을 내재하고 있습니다. 이는 러스트 메모리 안전 모델에서 벗어나있습니다.

또한 외부 함수의 인자 타입을 지정할 때, 러스트 컴파일러는 그것이 올바른지 보증할 수 없습니다. 따라서 보증 과정은 런타임에서 이루어집니다.

`extern`은 `{}`를 통해 전체 snappy API를 감쌀 수 있습니다:

```no_run
# #![feature(libc)]
extern crate libc;
use libc::{c_int, size_t};

#[link(name = "snappy")]
extern {
fn snappy_compress(input: *const u8,
input_length: size_t,
compressed: *mut u8,
compressed_length: *mut size_t) -> c_int;
fn snappy_uncompress(compressed: *const u8,
compressed_length: size_t,
uncompressed: *mut u8,
uncompressed_length: *mut size_t) -> c_int;
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
fn snappy_uncompressed_length(compressed: *const u8,
compressed_length: size_t,
result: *mut size_t) -> c_int;
fn snappy_validate_compressed_buffer(compressed: *const u8,
compressed_length: size_t) -> c_int;
}
# fn main() {}
```

# Creating a safe interface

보통 C API를 그대로 쓰기보다, 약간의 과정을 통해 메모리 안전을 보증받고 `vector`와 같은 높은 수준의 조작이 가능해져야 합니다. 이러한 방식으로 라이브러리에서 위험한 요소는 제한하고, 안전하고 높은 수준의 인터페이스만 제공되게 할 수 있습니다.

버퍼 관련 함수들은 러스트의 벡터를 조작할 때 쓰는 `slice::raw` 모듈을 사용하면서 달성해봅시다. 러스트의 벡터들은 메모리 주소에서 연속적이라는 것이 보증되어 있습니다. 길이(length)는 요소들의 갯수이며, 용량(capacity)은 할당된 요소의 메모리들의 총합입니다. 길이는 용량보다 작거나 같습니다.

```rust
# #![feature(libc)]
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
# fn main() {}
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
unsafe {
snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0
}
}
```

압축이 된 버퍼인지 검증하는 `validate_compressed_buffer`함수는 안에 `unsafe`를 감싸 사용함으로써, 안전성을 보증받게 됩니다.

`snappy_compress`와 `snappy_uncompress`함수는 과정이 약간 더 복잡한데, 결과를 저장할 버퍼가 미리 할당되어 있어야 하기 때문입니다.

`snappy_max_compressed_length`함수는 압축된 결과를 저장할 최대한의 용량을 가진 벡터를 할당할 수 있습니다. 이 벡터는 `snappy_compress`함수에 결과 파라미터로 넘겨질 수 있습니다. 또한 압축을 위한 길이 설정이 끝난 뒤에 실제 길이를 찾으려 할 때도 넘겨줍니다.

```rust
# #![feature(libc)]
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
# d: *mut size_t) -> c_int { 0 }
# unsafe fn snappy_max_compressed_length(a: size_t) -> size_t { a }
# fn main() {}
pub fn compress(src: &[u8]) -> Vec {
unsafe {
let srclen = src.len() as size_t;
let psrc = src.as_ptr();

let mut dstlen = snappy_max_compressed_length(srclen);
let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();

snappy_compress(psrc, srclen, pdst, &mut dstlen);
dst.set_len(dstlen as usize);
dst
}
}
```

압축해제(Decompression) 또한 snappy가 압축 예제에서 쓰였던 형식과 같이 `snappy_uncompressed_length`가 실제 버퍼 사이즈를 찾아줄 것이기 때문에 압축과 비슷합니다.

```rust
# #![feature(libc)]
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_uncompress(compressed: *const u8,
# compressed_length: size_t,
# uncompressed: *mut u8,
# uncompressed_length: *mut size_t) -> c_int { 0 }
# unsafe fn snappy_uncompressed_length(compressed: *const u8,
# compressed_length: size_t,
# result: *mut size_t) -> c_int { 0 }
# fn main() {}
pub fn uncompress(src: &[u8]) -> Option> {
unsafe {
let srclen = src.len() as size_t;
let psrc = src.as_ptr();

let mut dstlen: size_t = 0;
snappy_uncompressed_length(psrc, srclen, &mut dstlen);

let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();

if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 {
dst.set_len(dstlen as usize);
Some(dst)
} else {
None // SNAPPY_INVALID_INPUT
}
}
}
```

이 예제는 [library on GitHub](https://github.com/thestinger/rust-snappy).에서 볼 수 있으므로 참조하세요.

# Destructors

외부 라이브러리는 종종 호출 코드의 소유권을 무시하고 자원을 가져갑니다. 이런 일을 대비해, 가져간 자원을 안전하게 되돌리도록 파괴자(destructors)들을 러스트에서 제공하고 있습니다 (특히 panic의 경우)

파괴자(destructors)에 대해 더 자세히 알고 싶다면, [Drop trait](../std/ops/trait.Drop.html).

# Callbacks from C code to Rust functions

몇몇 외부 라이브러리들은 현재 상태나 중간 정보들을 다시 알려주기 위해 콜백을 사용할 필요가 있습니다. 이를 위해 러스트에서 정의된 함수들을 외부 라이브러리로 건네주는 것이 가능합니다. 그러한 콜백 함수는, C 코드로부터 올바르게 불리기 위해 `extern`으로 지정될 필요가 있습니다.

콜백 함수는 C 라이브러리에 등록을 통해 전달될 수 있으며, 그 후 거기에서 사용하면 됩니다.

간단한 예시로 가보죠.


러스트:

```no_run
extern fn callback(a: i32) {
println!("I'm called from C with value {0}", a);
}

#[link(name = "extlib")]
extern {
fn register_callback(cb: extern fn(i32)) -> i32;
fn trigger_callback();
}

fn main() {
unsafe {
register_callback(callback);
trigger_callback(); // Triggers the callback
}
}
```

C 코드:

```c
typedef void (*rust_callback)(int32_t);
rust_callback cb;

int32_t register_callback(rust_callback callback) {
cb = callback;
return 1;
}

void trigger_callback() {
cb(7); // Will call callback(7) in Rust
}
```

이 예제에서 러스트의 `main()`은 C의 `trigger_callback()`함수를 호출하고, 그 결과로 러스트의 `callback()`으로 돌아와서 호출됩니다.


## Targeting callbacks to Rust objects

바로 전 예시는 전역 함수가 어떻게 C 코드에서 호출될 수 있는지 살펴보았습니다.
하지만 러스트의 특정 객체에 콜백을 지정하고 싶다면? C의 객체를 위해 러스트 객체를 감싸서(wrapper) 표현해주면 됩니다.

이것은 객체의 포인터(raw pointer)를 C 라이브러리로 내리는 것으로 가능합니다. C 라이브러리는 알려주기만 한다면 러스트 객체의 포인터를 포함할 수 있습니다. 이 방법은 콜백이 안전하지 않은 러스트 참조 객체에 접근하게 될 수도 있습니다.

러스트 코드:

```no_run
#[repr(C)]
struct RustObject {
a: i32,
// other members
}

extern "C" fn callback(target: *mut RustObject, a: i32) {
println!("I'm called from C with value {0}", a);
unsafe {
// Update the value in RustObject with the value received from the callback
(*target).a = a;
}
}

#[link(name = "extlib")]
extern {
fn register_callback(target: *mut RustObject,
cb: extern fn(*mut RustObject, i32)) -> i32;
fn trigger_callback();
}

fn main() {
// Create the object that will be referenced in the callback
let mut rust_object = Box::new(RustObject { a: 5 });

unsafe {
register_callback(&mut *rust_object, callback);
trigger_callback();
}
}
```

C code:

```c
typedef void (*rust_callback)(void*, int32_t);
void* cb_target;
rust_callback cb;

int32_t register_callback(void* callback_target, rust_callback callback) {
cb_target = callback_target;
cb = callback;
return 1;
}

void trigger_callback() {
cb(cb_target, 7); // Will call callback(&rustObject, 7) in Rust
}
```

## Asynchronous callbacks

이전에 주어진 예시에서는 C 라이브러리의 함수를 호출하는 직접적인 반응으로 콜백이 일어났습니다. 러스트에서 C, 다시 러스트에서의 콜백 실행으로 제어되지만 결국 함수가 호출되고 콜백이 일어난 것은 같은 스레드 상에서 이루어집니다.

외부 라이브러리가 자신만의 스레드를 만들고 거기에서 콜백을 일으킨다면 일이 복잡해질 것입니다. 그럴 경우 콜백 안에서 러스트 데이타 구조에 접근하는 것은 매우 위험하며 적절한 동기화를 할 필요가 있습니다. 뮤텍스(metexes)와 같은 고전적인 동기화 방식뿐 아니라, 러스트는 채널(`std::commsync::mpsc`에 있는)을 사용하는 방법을 쓸 수 있습니다.

비동기 콜백이 러스트의 특정 객체를 대상으로 한다면, 해당 객체가 제거된 후에는 콜백이 C 라이브러리로부터 더 이상 일어나지 않아야합니다. 객체 파괴자(destructor)에서 콜백을 등록해제(unregistering)시키고 라이브러리에서 등록해제 후에는 콜백이 일어나지 않도록 설계하면 됩니다.


# Linking

The `link` attribute on `extern` blocks provides the basic building block for
instructing rustc how it will link to native libraries. There are two accepted
forms of the link attribute today:

* `#[link(name = "foo")]`
* `#[link(name = "foo", kind = "bar")]`

In both of these cases, `foo` is the name of the native library that we're
linking to, and in the second case `bar` is the type of native library that the
compiler is linking to. There are currently three known types of native
libraries:

* Dynamic - `#[link(name = "readline")]`
* Static - `#[link(name = "my_build_dependency", kind = "static")]`
* Frameworks - `#[link(name = "CoreFoundation", kind = "framework")]`

Note that frameworks are only available on OSX targets.

The different `kind` values are meant to differentiate how the native library
participates in linkage. From a linkage perspective, the rust compiler creates
two flavors of artifacts: partial (rlib/staticlib) and final (dylib/binary).
Native dynamic library and framework dependencies are propagated to the final
artifact boundary, while static library dependencies are not propagated at
all, because the static libraries are integrated directly into the subsequent
artifact.

A few examples of how this model can be used are:

* A native build dependency. Sometimes some C/C++ glue is needed when writing
some rust code, but distribution of the C/C++ code in a library format is just
a burden. In this case, the code will be archived into `libfoo.a` and then the
rust crate would declare a dependency via `#[link(name = "foo", kind =
"static")]`.

Regardless of the flavor of output for the crate, the native static library
will be included in the output, meaning that distribution of the native static
library is not necessary.

* A normal dynamic dependency. Common system libraries (like `readline`) are
available on a large number of systems, and often a static copy of these
libraries cannot be found. When this dependency is included in a rust crate,
partial targets (like rlibs) will not link to the library, but when the rlib
is included in a final target (like a binary), the native library will be
linked in.

On OSX, frameworks behave with the same semantics as a dynamic library.

# Unsafe blocks

Some operations, like dereferencing raw pointers or calling functions that have been marked
unsafe are only allowed inside unsafe blocks. Unsafe blocks isolate unsafety and are a promise to
the compiler that the unsafety does not leak out of the block.

Unsafe functions, on the other hand, advertise it to the world. An unsafe function is written like
this:

```rust
unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr }
```

This function can only be called from an `unsafe` block or another `unsafe` function.

# Accessing foreign globals

Foreign APIs often export a global variable which could do something like track
global state. In order to access these variables, you declare them in `extern`
blocks with the `static` keyword:

```no_run
# #![feature(libc)]
extern crate libc;

#[link(name = "readline")]
extern {
static rl_readline_version: libc::c_int;
}

fn main() {
println!("You have readline version {} installed.",
rl_readline_version as i32);
}
```

Alternatively, you may need to alter global state provided by a foreign
interface. To do this, statics can be declared with `mut` so we can mutate
them.

```no_run
# #![feature(libc)]
extern crate libc;

use std::ffi::CString;
use std::ptr;

#[link(name = "readline")]
extern {
static mut rl_prompt: *const libc::c_char;
}

fn main() {
let prompt = CString::new("[my-awesome-shell] $").unwrap();
unsafe {
rl_prompt = prompt.as_ptr();

println!("{:?}", rl_prompt);

rl_prompt = ptr::null();
}
}
```

Note that all interaction with a `static mut` is unsafe, both reading and
writing. Dealing with global mutable state requires a great deal of care.

# Foreign calling conventions

Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
conventions. Rust provides a way to tell the compiler which convention to use:

```rust
# #![feature(libc)]
extern crate libc;

#[cfg(all(target_os = "win32", target_arch = "x86"))]
#[link(name = "kernel32")]
#[allow(non_snake_case)]
extern "stdcall" {
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
}
# fn main() { }
```

This applies to the entire `extern` block. The list of supported ABI constraints
are:

* `stdcall`
* `aapcs`
* `cdecl`
* `fastcall`
* `Rust`
* `rust-intrinsic`
* `system`
* `C`
* `win64`

Most of the abis in this list are self-explanatory, but the `system` abi may
seem a little odd. This constraint selects whatever the appropriate ABI is for
interoperating with the target's libraries. For example, on win32 with a x86
architecture, this means that the abi used would be `stdcall`. On x86_64,
however, windows uses the `C` calling convention, so `C` would be used. This
means that in our previous example, we could have used `extern "system" { ... }`
to define a block for all windows systems, not just x86 ones.

# Interoperability with foreign code

Rust guarantees that the layout of a `struct` is compatible with the platform's
representation in C only if the `#[repr(C)]` attribute is applied to it.
`#[repr(C, packed)]` can be used to lay out struct members without padding.
`#[repr(C)]` can also be applied to an enum.

Rust's owned boxes (`Box`) use non-nullable pointers as handles which point
to the contained object. However, they should not be manually created because
they are managed by internal allocators. References can safely be assumed to be
non-nullable pointers directly to the type. However, breaking the borrow
checking or mutability rules is not guaranteed to be safe, so prefer using raw
pointers (`*`) if that's needed because the compiler can't make as many
assumptions about them.

Vectors and strings share the same basic memory layout, and utilities are
available in the `vec` and `str` modules for working with C APIs. However,
strings are not terminated with `\0`. If you need a NUL-terminated string for
interoperability with C, you should use the `CString` type in the `std::ffi`
module.

The standard library[`libc` crate on crates.io][libc] includes type aliases and function definitions for the C
standard library in the `libc` module, and Rust links against `libc` and `libm`
by default.

[libc]: https://crates.io/crates/libc

# The "nullable pointer optimization"

Certain types are defined to not be `null`. This includes references (`&T`,
`&mut T`), boxes (`Box`), and function pointers (`extern "abi" fn()`).
When interfacing with C, pointers that might be null are often used.
As a special case, a generic `enum` that contains exactly two variants, one of
which contains no data and the other containing a single field, is eligible
for the "nullable pointer optimization". When such an enum is instantiated
with one of the non-nullable types, it is represented as a single pointer,
and the non-data variant is represented as the null pointer. So
`Option c_int>` is how one represents a nullable
function pointer using the C ABI.

# Calling Rust code from C

You may wish to compile Rust code in a way so that it can be called from C. This is
fairly easy, but requires a few things:

```rust
#[no_mangle]
pub extern fn hello_rust() -> *const u8 {
"Hello, world!\0".as_ptr()
}
# fn main() {}
```

The `extern` makes this function adhere to the C calling convention, as
discussed above in "[Foreign Calling
Conventions](ffi.html#foreign-calling-conventions)". The `no_mangle`
attribute turns off Rust's name mangling, so that it is easier to link to.

# FFI and panics

It’s important to be mindful of `panic!`s when working with FFI. This code,
when called from C, will `abort`:

```rust
#[no_mangle]
pub extern fn oh_no() -> ! {
panic!("Oops!");
}
# fn main() {}
```

If you’re writing code that may panic, you should run it in another thread,
so that the panic doesn’t bubble up to C:

```rust
use std::thread;

#[no_mangle]
pub extern fn oh_no() -> i32 {
let h = thread::spawn(|| {
panic!("Oops!");
});

match h.join() {
Ok(_) => 1,
Err(_) => 0,
}
}
# fn main() {}
```
A `panic!`
across an FFI boundary is undefined behavior. If you’re writing code that may
panic, you should run it in another thread, so that the panic doesn’t bubble up
to C:

```rust
use std::thread;

#[no_mangle]
pub extern fn oh_no() -> i32 {
let h = thread::spawn(|| {
panic!("Oops!");
});

match h.join() {
Ok(_) => 1,
Err(_) => 0,
}
}
# fn main() {}
```

# Representing opaque structs

Sometimes, a C library wants to provide a pointer to something, but not let you
know the internal details of the thing it wants. The simplest way is to use a
`void *` argument:

```c
void foo(void *arg);
void bar(void *arg);
```

We can represent this in Rust with the `c_void` type:

```rust
# #![feature(libc)]
extern crate libc;

extern "C" {
pub fn foo(arg: *mut libc::c_void);
pub fn bar(arg: *mut libc::c_void);
}
# fn main() {}
```

This is a perfectly valid way of handling the situation. However, we can do a bit
better. To solve this, some C libraries will instead create a `struct`, where
the details and memory layout of the struct are private. This gives some amount
of type safety. These structures are called ‘opaque’. Here’s an example, in C:

```c
struct Foo; /* Foo is a structure, but its contents are not part of the public interface */
struct Bar;
void foo(struct Foo *arg);
void bar(struct Bar *arg);
```

To do this in Rust, let’s create our own opaque types with `enum`:

```rust
pub enum Foo {}
pub enum Bar {}

extern "C" {
pub fn foo(arg: *mut Foo);
pub fn bar(arg: *mut Bar);
}
# fn main() {}
```

By using an `enum` with no variants, we create an opaque type that we can’t
instantiate, as it has no variants. But because our `Foo` and `Bar` types are
different, we’ll get type safety between the two of them, so we cannot
accidentally pass a pointer to `Foo` to `bar()`.

for-loops
Deleted file
functions
# 5.2. 함수 (Functions) - 1090%

모든 Rust 프로그램은 최소한 하나의 함수를 가집니다. 바로 `main` 함수죠.

```rust
fn main() {
}
```

이 것은 가능한위의 코드는 가장 한 함수 선언입니다. 전에 언급했듯이, `fn`는 ‘이것은 함수이다.’라는 뜻이고, 입니다. 그 다음엔 '이름'이 오고, 이 함수는 인자를 취하지 않기 때문에 '빈 괄호'가 오고, 몸체를 나타내는 '중괄호'가 옵니다. 다음 함수의 이름은 `foo` 입니다.

```rust
fn foo() {
}
```

이제, 인자를 받아볼까요? 여기 숫자를 출력하는 함수가 있습니`print_number` 함수를 만들어봅시다.

```rust
fn print_number(x: i32) {
println!("x is: {}", x);
}
```

여기아래는 `print_number` 함수를 사용하는 완전한 프로그램이 있습니다.

```rust
fn main() {
print_number(5);
}

fn print_number(x: i32) {
println!("x is: {}", x);
}
```

보시다시피, 함수 인자는 `let` 선언과 아주 유사하게 동작합니다. 인자 이름 다음 `:`(콜론)을 적고 타입을 적습니다.

다음은 두 수를 더하고 출력하는 완전한 프로그램입니다.

```rust
fn main() {
print_sum(5, 6);
}

fn print_sum(x: i32, y: i32) {
println!("sum is: {}", x + y);
}
```

함수를 호출하거나 선언할 때는 쉼표로 인자를 분리합니다.

`let`과는 다르게 함수 인자의 타입을 _꼭_ 선언해야 합니다. 다음 예제는 동작하지 않습니다.

```rust,ignore
fn print_sum(x, y) {
println!("sum is: {}", x + y);
}
```

이 에러가 표시될 것입니다.

```text
expected one of `!`, `:`, or `@`, found `)`
fn print_number(x, y) {
```

이는 신중하게 결정한 설계입니다. Haskell 처럼, 전체 프로그램의 추론이 가능한 언어라면, 종종 타입을 명시적으로 기록하는 것이 최선책입니다. 우리좋습니다. Rust는 함수 선언에선 타입을 명시하길 강제하면서도해야 하지만, 함수의 내부에서는 추론을 허용합니다(즉, 명시하지 않아도 됩니다). 이것은 추론과 명시 사이에서 적절한 합의점이 됩니다.

값의 '반환'에 대해 알아볼까요? 다음은 정수에 1을 더하는 함수입니다.

```rust
fn add_one(x: i32) -> i32 {
x + 1
}
```

Rust의 함수는 정확히 하나의 값만 반환하고, 대시 (`-`) 뒤에 초과 기호 (`>`)인 ‘화살표’ 다음에 타입을 선언합니다. 함수의 마지막 줄 반환되는 것을 결정합니다. 세미콜론이 누락되었빠졌다는 것을 눈치채셨나요? 추가해 보겠습니다.

```rust,ignore
fn add_one(x: i32) -> i32 {
x + 1;
}
```

그러면, 에러가 표시될 것입세미콜론을 추가하면 에러가 납니다.

```text
error: not all control paths return a value
fn add_one(x: i32) -> i32 {
x + 1;
}

help: consider removing this semicolon:
x + 1;
^
```

이는 Rust에 대한 두가지 흥미로운 점독특한 성질을 보여줍니다. '표현식' 기반의 언어라는 점과, 세미콜론이 '중괄호와 세미콜론' 기반의 언어에서의 세미콜론과 다르다는 것입니다. 이 두 가지는 연관이 있습니다.

## 표현식 vs. 구문 (Expressions vs. Statements)

Rust은 기본적으로 표현식 기반 언어입니다. 구문은 오직 두 종류만 있고, 나머지는 모두 표현식입니다.

근데구문과 표현식은 무엇이 다른가를까요? 표현식은 값을 반환하고, 구문은 반환값이 없습니다. 이것은 결국 '모든 제어 흐름이 값을 반환하지 않습니다(not all control paths return a value)'가 에러 메세지로 나타난 이유입니다: `x + 1;` 구문은 값을 반환하지 않습니다. Rust에는 두 종류의 구문이 있습니다. ‘선언문’ 과 ‘표현문’ 입니다. 나머지는 전부 표현식입니다. 우선 선언문에 대해 이야기 해볼까요?

Ruby와 같은 언어에서는 변수 바인딩은 구문이 아닌, 표현식으로 작성될 수 있습니다.

```ruby
x = y = 5
```

그러나 Rust에서는, 바인딩이 표현식이 _아니다_는 것을 알려주기 위해 `let`을 사용합니다. 다음은 컴파일시에 에러를 발생시킬 것입니다.

```ignore
let x = (let y = 5); // expected identifier, found keyword `let`
```

컴파일러는 표현식의 시작을 기대했으나, `let`은 오직 구문만이 될 수 있습니다.

비록 그 값이 딱히 쓰이진 않더라도, 변수에 값을 할당하는 것(e.g. `y = 5`)이 여전히 표현식이라는 것에 주목하세요. 할당하는 행위 자체가 할당된 값을 평가하는(e.g. 이전 예제에서 `5`) 다른 언어들과 달리, 러스트에서 값의 할당은 빈 튜플인 `()`이 됩니다. 할당된 값은 [단 하나의 소유자](ownership.htmlmd)를 가지기 때문입니다. 따라서 반환된 값은 매우 놀라울 것입니다:

```rust
let mut y = 5;

let x = (y = 6); // x has the value `()`, not `6`
```

두 번째 문장은 러스트에서 *표현문(expression statement)*이 됩니다. 어떤 표현식이든 구문으로 바꾸기 위해 존재합니다. 현실적인 조건으로, 러스트의 문법에서 구문은 다른 구문을 따르기를 기대합니다. 각각에서 표현식을 분리하려면 세미콜론을 사용합니다. 러스트는 다른 언어들과 같이 줄의 끝마다 세미콜론을 필요로 하는 것을 뜻하고, 실제로 러스트 코드의 줄마다 대부분 세미콜론을 볼 수 있을 것입니다.

"대부분"이라면 그 예외가 무엇일까요? 이미 보았듯이, 이러한 코드입니다:

```rust
fn add_one(x: i32) -> i32 {
x + 1
}
```

우리의 함수는 `i32`를 반환한다고 했지만, 세미콜론을 쓴다면 `()`를 반환할 것입니다. 그렇기 때문에 러스트는 아마 이것이 우리가 원하는 결과가 아님을 알고, 세미콜론을 제거해보라는 제안을 한 것입니다.

## 미리 반환 (Early returns)

근데 미리 반환하려면 어떻게 해야하나요? Rust는 이를 위한 키워드인 `return`을 가지고 있습니다.

```rust
fn foo(x: i32) -> i32 {
return x;

// we never run this code!
x + 1
}
```

함수의 마지막 줄에 `return`을 사용할 수도 있지만, 좋지않은 스타일이라고 생각합일반적으로 좋은 방법은 아닙니다.

```rust
fn foo(x: i32) -> i32 {
return x + 1;
}
```

이전에 표현식 기반의 언어로 작업해보지 않았다면, 앞서 나온 `return` 없는 정의는 좀 이상하게 보일 수 있습니다. 그러나 때로는 더 직관적일 수 있습니다.

## Diverging functions

러스트는 리턴을 하지 않는, '발산하는 함수(diverging functions)'를 위한 특별한 문법을 가지고 있습니다.

```rust
fn diverges() -> ! {
panic!("This function never returns!");
}
```

`panic!`은 `println!()`과 비슷한 매크로입니다. `println()`과 다른점은 `panic()`은 현재 실행하고 있는 스레드를 충돌시키고 메세지를 전달합니다.

함수가 충돌되었기 때문에 어떠한 것도 반환하지 않고, 그렇기 때문에 "벗어났다(diverges)"라고 읽는 `!` 타입을 가집니다. 발산하는 함수는 어떤 타입으로도 쓸 수 있습니다:

```should_panic
# fn diverges() -> ! {
# panic!("This function never returns!");
# }
let x: i32 = diverges();
let x: String = diverges(
()`은 `println!()`과 비슷한 매크로입니다. `println!()`과 다른점은 `panic!()`은 현재 실행하고 있는 스레드를 충돌시키고 메세지를 전달합니다. Because this function will cause a crash, it will never
return, and so it has the type ‘`!`’, which is read ‘diverges’.

If you add a main function that calls `diverges()` and run it, you’ll get
some output that looks like this:

```text
thread ‘
’ panicked at ‘This function never returns!’, hello.rs:2
```

If you want more information, you can get a backtrace by setting the
`RUST_BACKTRACE` environment variable:

```text
$ RUST_BACKTRACE=1 ./diverges
thread '
' panicked at 'This function never returns!', hello.rs:2
stack backtrace:
1: 0x7f402773a829 - sys::backtrace::write::h0942de78b6c02817K8r
2: 0x7f402773d7fc - panicking::on_panic::h3f23f9d0b5f4c91bu9w
3: 0x7f402773960e - rt::unwind::begin_unwind_inner::h2844b8c5e81e79558Bw
4: 0x7f4027738893 - rt::unwind::begin_unwind::h4375279447423903650
5: 0x7f4027738809 - diverges::h2266b4c4b850236beaa
6: 0x7f40277389e5 - main::h19bb1149c2f00ecfBaa
7: 0x7f402773f514 - rt::unwind::try::try_fn::h13186883479104382231
8: 0x7f402773d1d8 - __rust_try
9: 0x7f402773f201 - rt::lang_start::ha172a3ce74bb453aK5w
10: 0x7f4027738a19 - main
11: 0x7f402694ab44 - __libc_start_main
12: 0x7f40277386c8 -
13: 0x0 -
```

`RUST_BACKTRACE` also works with Cargo’s `run` command:

```text
$ RUST_BACKTRACE=1 cargo run
Running `target/debug/diverges`
thread '
' panicked at 'This function never returns!', hello.rs:2
stack backtrace:
1: 0x7f402773a829 - sys::backtrace::write::h0942de78b6c02817K8r
2: 0x7f402773d7fc - panicking::on_panic::h3f23f9d0b5f4c91bu9w
3: 0x7f402773960e - rt::unwind::begin_unwind_inner::h2844b8c5e81e79558Bw
4: 0x7f4027738893 - rt::unwind::begin_unwind::h4375279447423903650
5: 0x7f4027738809 - diverges::h2266b4c4b850236beaa
6: 0x7f40277389e5 - main::h19bb1149c2f00ecfBaa
7: 0x7f402773f514 - rt::unwind::try::try_fn::h13186883479104382231
8: 0x7f402773d1d8 - __rust_try
9: 0x7f402773f201 - rt::lang_start::ha172a3ce74bb453aK5w
10: 0x7f4027738a19 - main
11: 0x7f402694ab44 - __libc_start_main
12: 0x7f40277386c8 -
13: 0x0 -
```

발산하는 함수는 어떤 타입으로도 쓸 수 있습니다.

```should_panic
# fn diverges() -> ! {
# panic!("This function never returns!");
# }
let x: i32 = diverges();
let x: String = diverges();
```

## Function pointers

We can also create variable bindings which point to functions:

```rust
let f: fn(i32) -> i32;
```

`f` is a variable binding which points to a function that takes an `i32` as
an argument and returns an `i32`. For example:

```rust
fn plus_one(i: i32) -> i32 {
i + 1
}

// without type inference
let f: fn(i32) -> i32 = plus_one;

// with type inference
let f = plus_one;
```

We can then use `f` to call the function:

```rust
# fn plus_one(i: i32) -> i32 { i + 1 }
# let f = plus_one;
let six = f(5);
```
guessing-game
# 3.1. 추리 게임 (Guessing Game) - 100%

첫 프로젝트로 우리는 고전적인 초보자용 프로그래밍 문제인 추리 게임을 구현할 것입니다. 이 프로그램은 다음과 같이 동작합니다. 우리 프로그램은 1부터 100 사이의 정수형 난수를 생성합니다. 그리고 나서 우리에게 예측값을 입력받습니다. 우리에게 입력을 받은 프로그램은 그 값이 너무 작거나 너무 크면 우리에게 알려줍니다. 우리가 정확한 값을 예측하는 데 성공하면, 프로그램은 우리를 칭찬해 줄 것입니다. 괜찮죠?

# 구성

새 프로젝트를 구성해 봅시다. 여러분의 프로젝트 디렉터리에 가 주세요. `hello_world`를 위해서 디렉터리 구조와 `Cargo.toml`을 만들었던 방법을 기억하고 있으신가요? Cargo는 이 작업을 우리 대신 해 주는 명령어를 가지고 있습니다. 한번 보도록 합시다.


```bash
$ cd ~/projects
$ cargo new guessing_game --bin
$ cd guessing_game
```

우리는 `cargo new`에게 프로젝트의 이름과 함께 `--bin` 플래그를 넘겨주었습니다. 라이브러리가 아니라 바이너리를 만들고 있기 때문입니다.

생성된 `Cargo.toml`의 내용을 확인해 봅시다.

```toml
[package]

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

Cargo는 여러분의 환경으로부터 이 정보를 얻습니다. 만약 틀린 부분이 있다면 가서 고치세요.

마지막으로, Cargo는 우리를 위해서 'Hello, world' 프로그램을 작성해 두었습니다. `src/main.rs`를 확인해 보세요.

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

Cargo가 만들어 준 것을 컴파일해 봅시다.

```{bash}
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
```

훌륭하군요! 여러분의 `src/main.rs`를 다시 열어 봅니다. 우리는 이 파일에 모든 코드를 작성할 것입니다.

나아가기 전에, 또 다른 Cargo 명령어를 보여드리겠습니다. `run`입니다. `cargo run`은 `cargo build`와 비슷한 것이지만, 이것은 그 이후 생성된 실행 파일을 실행합니다. 시도해 봅시다.

```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/debug/guessing_game`
Hello, world!
```

좋군요! `run` 명령어는 여러분이 하나의 프로젝트를 빠르게 반복해야 할 때에 편리합니다. 우리 게임이 바로 그런 프로젝트이죠. 다음 것으로 넘어가기 전에 빠르게 각 반복을 테스트할 필요가 있습니다.


# 추측을 처리하기

시작해 봅시다! 추리 게임에서 처음으로 해야 할 것은 우리 플레이어들에게 예측값을 입력할 수 있도록 하는 것입니다. 이것을 여러분의 `src/main.rs` 에 넣으세요.

```rust,no_run
use std::io;

fn main() {
println!("Guess the number!");

println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("Failed to read line");

println!("You guessed: {}", guess);
}
```

상당히 많군요! 조금씩 살펴보도록 합시다.

```rust,ignore
use std::io;
```

우리는 사용자 입력을 받고 결과를 출력해야 합니다. 그러므로 우리는 표준 라이브러리의 `io` 라이브러리가 필요합니다. 기본적으로, Rust가 모든 프로그램에 임포트하는 것은 ['서곡'][prelude]이라 불리는 아주 작은 라이브러리 뿐입니다. 만약 서곡에 들어 있지 않은 것을 사용하고 싶다면, 여러분은 그것을 직접적으로 `use`해야 합니다.


[prelude]: ../std/prelude/index.html

```rust,ignore
fn main() {
```

이전에 보셨던 것처럼, `main()` 함수는 여러분의 프로그램으로 들어가는 진입점입니다. `fn` 문법은 새 함수를 선언하며, `()`는 매개 변수가 없다는 것을 나타냅니다. 그리고 `{`는 함수의 몸체를 시작합니다. 우리가 반환 타입을 포함시키지 않았기 때문에, 빈 [튜플][tuples]인 `()`으로 간주됩니다.


[tuples]: primitive-types.html#tuples

```rust,ignore
println!("Guess the number!");

println!("Please input your guess.");
```

우리는 `println!()`이 화면에 [문자열][strings]을 출력하는 [매크로][macros]라는 것을 이전에 배운 적이 있습니다.

[macros]: macros.html
[strings]: strings.html

```rust,ignore
let mut guess = String::new();
```

점점 흥미로워지고 있군요! 이 짧은 줄에 많은 것이 일어나고 있습니다. 첫 번째로 눈치챌 수 있는 것은, 이것은 '변수 결합'을 만드는 데 사용되는 [let 구문][let]이라는 것입니다. 이것들은 다음과 같은 형태를 취합니다.

```rust,ignore
let foo = bar;
```

[let]: variable-bindings.html

이것은 `foo`라는 이름의 새 결합을 만들고, 그것을 값 `bar`에 결합합니다. 많은 언어들에서 이것은 '변수'라고 불립니다만, Rust의 변수 결합은 몇 가지 특이한 점들을 가지고 있습니다.

예를 들어서, Rust의 변수들은 기본적으로 [변경 불가능][immutable]합니다. 그래서 우리는 이 예제에서 `mut`를 사용한 것입니다. 이것은 이 결합을 변경할 수 있도록 만듭니다. `let`은 좌변에 이름을 취하는 대신, 사실은 '[패턴][patterns]'을 받습니다. 우리는 더 나중에 패턴을 사용할 것입니다. 지금으로서는 충분히 사용할 수 있을 정도로 간단합니다.


```rust
let foo = 5; // immutable.
let mut bar = 5; // mutable
```

[immutable]: mutability.html
[patterns]: patterns.html

오, 그리고 `//` 은 그것이 있는 줄의 마지막까지를 주석으로 만듭니다. Rust는 [주석][comments] 속의 모든 내용을 무시합니다.

[comments]: comments.html

그러므로 지금 우리는 `let mut guess`가 이름이 `guess`인, 새 변경 가능한 결합을 도입한다는 것을 알고 있습니다. 그러나 거기에 결합될, 그 반대편에 있는 `String::new()`에 대해서도 보아야겠죠.


`String`은 표준 라이브러리에서 제공하는 문자열 타입입니다. [`String`][string]은 자라날 수 있는 UTF-8 텍스트입니다.


[string]: ../std/string/struct.String.html

`::new()` 문법에서 `::`를 사용하는 이유는 이것이 어떤 특정한 타입과 '연결된 함수'이기 때문입니다. 이것은 다시 말해서 new() 함수가 `String`의 인스턴스 하나하나에 연결되는 것이 아니라, `String` 그 자체에 연결되어 있다는 것을 말합니다. 일부 언어들은 이것을 '정적 메서드'라고 부릅니다.

이 함수는 빈 `String`을 새로 만들기 때문에 `new()`라는 이름을 가지고 있습니다. 어떤 종류의 새로운 값을 만드는 데 흔하게 사용되는 이름이기 때문에, 여러분은 많은 타입들에서 `new()` 함수를 보게 될 것입니다.


다시 진행해 봅시다.

```rust,ignore
io::stdin().read_line(&mut guess)
.ok()
.expect("Failed to read line");
```

아주 많은 것이 있군요! 하나하나씩 봅시다. 첫 번째 줄은 두 부분으로 이루어져 있습니다. 다음이 첫 번째 부분입니다.

```rust,ignore
io::stdin()
```

프로그램의 첫 줄에서 `std::io`를 `use` 했던 것을 기억하고 있습니까? 이제 우리는 거기에 연결된 함수들을 호출합니다. 만약 우리가 `use std::io`를 하지 않았다면, 우리는 이 줄을 `std::io::stdin()`으로 쓸 수도 있었습니다.

이 특별한 함수는 여러분의 터미널의 표준 입력에 대한 핸들을 반환합니다. 더 자세히 알고 싶으면 [std::io::Stdin][iostdin]을 참고하세요.

[iostdin]: ../std/io/struct.Stdin.html

다음 부분은 이 핸들을 사용자로부터 입력을 받는 데 사용할 것입니다.

```rust,ignore
.read_line(&mut guess)
```

여기에서 핸들에게 [`read_line()`][read_line] 메서드를 호출합니다. [메서드][method]는 연결된 함수와 비슷하지만, 그 타입 자체가 아니라 그 타입의 각 인스턴스들에서만 사용할 수 있습니다. 우리는 또한 `read_line`에 매개변수 하나(`&mut guess`)를 넘기고 있습니다.

[read_line]: ../std/io/struct.Stdin.html#method.read_line
[method]: method-syntax.html

위에서 `guess`를 어떻게 결합하는지 기억하고 계신가요? 우리는 이게 변경 가능하다고 말했었습니다. 그러나, `read_line`은 `String`을 매개변수로 취하지 않고, 대신 `&mut String`을 취합니다. Rust는 '[참조][references]'라고 부르는 기능을 가지고 있습니다. 이 기능은 하나의 데이터 조각에 대해 여러 개의 참조를 가질 수 있도록 해서, 복사 회수를 줄일 수 있습니다. Rust의 주요 특장점 중 하나가 레퍼런스를 쉽고 안전하게 사용할 수 있다는 점인 것처럼, 참조는 복잡한 기능입니다. 그러나 우리 프로그램을 마치기 위해서 자세한 내용들을 알아야 할 필요는 없습니다. 지금으로서는, 우리가 알아야 할 것은 `let` 결합처럼, 참조는 기본적으로 변경 불가능하다는 것입니다. 따라서, 우리는 `&guess` 대신 `&mut guess`를 써야 합니다.

`read_line()`이 문자열에 대한 변경할 수 있는 참조를 취하는 이유는 무엇일까요? 이 함수의 역할은 사용자가 표준 입력에 넣은 것을 가져다가 문자열 안쪽에 놓는 것입니다. 따라서 이 함수는 문자열을 매개변수로 받아서 거기에 입력을 더해야 하므로 참조는 변경 가능해야 합니다.


[references]: references-and-borrowing.html

그러나 아직도 이 코드에서 보아야 할 것이 남아 있습니다. 단 한 줄으로 이뤄져 있지만, 이 코드에 담긴 논리의 첫 부분에 지나지 않습니다.

```rust,ignore
.ok()
.expect("Failed to read line");
```

`.foo()` 문법으로 메서드를 호출하려고 할 때, 여러분은 새 줄을 만들거나 다른 공백 문자를 사용하게 될지도 모릅니다. 이렇게 함으로써 길이가 아주 긴 코드를 여러 개로 나눌 수 있습니다. 우리는 다음과 같이 _할 수도_ 있었습니다.

```rust,ignore
io::stdin().read_line(&mut guess).ok().expect("failed to read line");
```

하지만 이러면 읽기가 어렵습니다. 그래서 우리는 세 개의 메서드 호출을 세 줄에 나누어 쓴 것입니다. 지금까지 앞에서 `read_line()`에 대해서 말했습니다. 그러나 대체 `ok()`와 `expect()`는 뭘까요? 뭐, 우리는 `read_line()`이 사용자의 입력을 우리가 넘긴 `&mut String`에 넣는다고 했었습니다. 그러나 이 함수도 값을 하나 반환합니다. 이 경우에 반환값은 [`io::Result`][ioresult]가 됩니다. Rust의 표준 라이브러리에는 `Result`라는 이름의 타입이 여럿 있는데, 일반적인 버전의 [`Result`][result]와 `io::Result` 같은 종속 라이브러리들에 대한 특화된 버전들이 있습니다.

[ioresult]: ../std/io/type.Result.html
[result]: ../std/result/enum.Result.html

이러한 `Result` 타입들의 목적은 오류 처리 정보를 기록하는 것입니다. 여느 타입들과 마찬가지로 `Result` 타입의 값들은 그 타입에 대해 정의된 메서드를 가지고 있습니다. 예컨대 `io::Result`에는 `ok()` 메서드가 있습니다. 이 메서드가 말하고자 하는 바는 '나는 이 값이 성공적인 것이라고 가정하려 한다'는 뜻입니다. 만약 그렇지 않다면, 이 메서드는 오류 정보를 그냥 던져버립니다. 어째서 던져버리냐고요? 뭐, 기초적인 프로그램이기 때문에 그냥 일반적인 오류를 출력하고 싶거든요. 어떠한 문제든 기본적으로는 더 진행할 수가 없다는 것을 의미하기 때문입니다. 이 [`ok()` 메서드][ok]는 또 다른 메서드 `expect()`가 정의된 다른 값을 반환합니다. 이 [`expect()` 메서드][expect]는 자신이 호출된 값이 성공적인 것이 아니라면, 여러분이 넘긴 메시지를 가지고 [`panic!`][panic]을 호출합니다. 이런 `panic!`은 우리가 만든 프로그램이 메시지를 출력하고 나서 기능을 멈추도록 만듭니다.


[ok]: ../std/result/enum.Result.html#method.ok
[expect]: ../std/option/enum.Option.html#method.expect
[panic]: error-handling.html

만약 이 두 개의 메서드를 떼어낸다면, 우리 프로그램은 컴파일이 되겠지만 다음과 같은 경고가 나오게 됩니다.

```bash
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
src/main.rs:10:5: 10:39 warning: unused result which must be used,
#[warn(unused_must_use)] on by default
src/main.rs:10 io::stdin().read_line(&mut guess);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Rust가 우리에게 사용되지 않은 `Result` 값이 있다고 경고합니다. 이 경고는 `io::Result`가 가지고 있는 특별한 참고용 주석_annotation_으로부터 왔습니다. Rust는 발생할 수 있지만 여러분이 처리하지 않은 에러에 대해 말하려고 시도합니다. 이러한 오류를 숨기기 위한 올바른 방법은 실제로 에러 처리 코드를 작성하는 것입니다. 다행히도 문제가 있을 때 그냥 동작을 멈추고 싶다면 위의 두 메서드를 사용하면 됩니다. 만약 어떤 방식으로든 오류로부터 복구하고 싶다면 다른 무언가를 하게 될 테지만, 그것은 나중의 프로젝트로 미루도록 하겠습니다.

이제 첫 예제의 마지막 줄이 남았습니다.

```rust,ignore
println!("You guessed: {}", guess);
}
```

우리가 입력을 저장했던 문자열을 출력합니다. `{}`는 자리 표시자입니다. 그리고 우리는 거기에 `guess`를 매개 변수로 넘깁니다. 혹시 여러 개의 `{}`가 있다면, 다음처럼 여러 개의 매개 변수를 넘기게 될 것입니다.

```rust
let x = 5;
let y = 10;

println!("x and y: {} and {}", x, y);
```

쉽군요.

어쨌든 그렇습니다. `cargo run`을 통해 지금까지 한 것을 실행할 수 있습니다.

```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/debug/guessing_game`
Guess the number!
Please input your guess.
6
You guessed: 6
```

좋습니다! 이제 첫 번째 부분은 끝났습니다. 이제 우리는 키보드로부터 입력을 받고, 그걸 다시 출력할 수 있습니다.


# 숨김수 생성하기

이제 우리는 숨김수를 만들어야 합니다. Rust는 아직 표준 라이브러리에 난수 기능을 포함하고 있지 않습니다. 그러나 Rust 팀은 [`rand` 크레이트][randcrate]를 제공합니다. '크레이트'는 Rust 코드의 패키지입니다. 우리는 지금까지 실행 가능한 '바이너리 크레이트'를 만들고 있었습니다. 반면에 `rand`는 '라이브러리 크레이트'입니다. 라이브러리 크레이트는 다른 프로그램들이 사용하도록 의도된 코드들을 담고 있습니다.

[randcrate]: https://crates.io/crates/rand

외부 크레이트를 사용할 때야말로 Cargo가 빛을 보는 때입니다. 우리가 `rand`를 쓰는 코드를 작성하기 전에, `Cargo.toml`을 수정해야 합니다. 다음 몇 줄을 파일의 뒤에 추가하세요.

```toml
[dependencies]

rand="0.3.0"
```

`Cargo.toml` 파일의 `[dependencies]` 절은 `[package]` 절과 비슷합니다. 다음 절이 시작하기 전까지 등장하는 것들이 그 일부분입니다. Cargo는 외부 크레이트에 대한 의존성 여부와 필요한 버전을 알기 위해 dependencies 절을 사용합니다. 이 경우 우리는 명시적으로 `0.3.0`을 사용했습니다. which Cargo understands to be any release that’s compatible with this specific version. Cargo는 버전 번호를 쓰는 표준적인 방법인 [의미적 버전 매기기][semver]를 이해합니다. 정확히 `0.3.0` 버전만 사용하고 싶다면, `=0.3.0`을 사용할 수 있습니다. 만약 최신 버전을 사용하고 싶다면 `*`를 이용할 수 있고, 사용할 버전의 범위를 적을 수도 있습니다. 더 자세한 정보를 위해서는 [Cargo 문서][cargodoc]을 보시기 바랍니다.

[semver]: http://semver.org
[cargodoc]: http://doc.crates.io/crates-io.html

이제 우리 프로젝트를 빌드해 봅시다.

```bash
$ cargo build
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading rand v0.3.8
Downloading libc v0.1.6
Compiling libc v0.1.6
Compiling rand v0.3.8
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
```

(물론 다른 버전을 보실 수도 있습니다.)

새로운 출력이 많군요! 이제 우리는 외부 의존성을 가지고 있고, Cargo는 [Crates.io][cratesio] 데이터의 사본인 레지스트리로부터 최신 버전들을 가져옵니다. Crates.io는 Rust 생태계에 속한 사람들이 자신들의 오픈 소스 프로젝트를 다른 이들이 사용할 수 있도록 올리는 곳입니다.

[cratesio]: https://crates.io

레지스트리를 업데이트한 다음, Cargo는 우리 `[dependencies]`를 확인하고, 아직 가지고 있지 않은 것들을 내려받습니다. 지금 우리는 `rand`에만 의존하고 싶다고 말했지만 `libc`의 사본 또한 가져왔습니다. 그 이유는 `rand`의 동작이 `libc`에 의존하기 때문입니다. Cargo는 이들을 내려받아 컴파일하고, 다음으로 우리 프로젝트를 컴파일합니다.

`cargo build`를 다시 실행하면, 이번에는 다른 출력을 얻습니다.

```bash
$ cargo build
```

맞습니다. 출력이 없군요! Cargo는 우리 프로젝트가 이미 빌드되었고, 프로젝트가 의존하고 있는 모든 것이 빌드되어 있음을 알고 있습니다. 따라서 그것들을 다시 수행할 이유가 없고, 이제 할 것이 없으므로 그냥 종료합니다. 만약 `src/main.rs`를 다시 열어서 약간 수정하고 다시 저장한다면 다음 한 줄을 보게 될 것입니다.

```bash
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
```

우리는 Cargo에게 `rand`의 `0.3.x`버전이라면 뭐든지 좋다고 말했으므로, Cargo는 이 글이 쓰이는 시점에서 최신 버전인 `v0.3.8`을 가져옵니다. 그러나 만약 중요한 버그 수정을 위해 다음 주에 `v0.3.9`가 나온다면 어떻게 될까요? 버그 수정은 중요하지만, 만약 `0.3.9`가 우리 코드를 깨지게 만드는 수정 내용을 가지고 있다면 어떨까요?

이 문제의 답은 `Cargo.lock` 파일입니다. 이 파일은 여러분의 프로젝트 디렉터리에서 찾을 수 있습니다. 프로젝트를 처음 빌드할 때 Cargo는 여러분의 조건에 맞는 모든 버전을 계산하고, 그것을 `Cargo.lock` 파일에 적습니다. 나중에 여러분의 프로젝트를 다시 빌드하면, Cargo는 `Cargo.lock` 파일이 존재하는 것을 보고, 새로 버전을 확인하기보다는 거기에 적혀 있는 버전을 사용합니다. 이로 인해 여러분은 자동적으로 빌드를 반복할 수 있습니다. 무슨 말이냐면, lock 파일 덕분에 우리는 명시적으로 업그레이드하기 전까지는 `0.3.8` 버전에 머무른다는 말이죠. 그리고 우리 코드를 공유하는 다른 모든 사람들 또한 그렇습니다.

`v0.3.9`를 사용하고 싶다면 어떻게 _해야_ 할까요? Cargo는 `update`라는 또 다른 명령어를 갖고 있습니다. 이것은 'lock을 무시하고, 우리가 명세한 것에 들어맞는 최신 버전을 찾아내어, 있다면 lock 파일에 그 버전을 기록하라'는 의미입니다. 그렇지만 Cargo는 기본적으로 `0.3.0`보다 크고 `0.4.0`보다 작은 버전만을 찾습니다. 만약 `0.4.x`로 옮기고 싶다면, 우리는 `Cargo.toml`을 직접 수정해야 할 것입니다. 그렇게 한 후에 `Cargo build`를 실행하면, Cargo는 우리의 `rand` 요구사항을 다시 평가하여 색인을 갱신할 것입니다.

[Cargo][doccargo]와 [그 생태계][doccratesio]에 대해서는 할 말이 많지만, 지금 필요한 것은 모두 설명했습니다. Cargo는 라이브러리 재사용을 매우 쉽게 만들기 때문에, Rust인들은 많은 부패키지를 조립한 작은 프로젝트를 작성하는 경향이 있습니다.

[doccargo]: http://doc.crates.io
[doccratesio]: http://doc.crates.io/crates-io.html

이제 실제로 `rand`를 _사용해_ 봅시다.

```rust,ignore
extern crate rand;

use std::io;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

println!("You guessed: {}", guess);
}
```

가장 먼저 첫 번째 줄을 바꿨습니다. 이제 `extern crate rand` 라고 되어 있군요. 우리의 `[dependencies]`에 `rand`를 선언했기 때문에, Rust에게 우리가 이것을 사용하겠다고 알리기 위해 `extern crate`를 사용할 수 있습니다. 이 명령은 동시에 `use rand`와 같은 역할을 수행하기 때문에, 우리는 `rand` 크레이트 내부의 어떤 것이든 `rand::`라는 접두어를 붙여 사용할 수 있습니다.

다음으로, 우리는 또 다른 `use` 라인을 추가했습니다. 그 내용은 `use rand::Rng`입니다. 어떤 메서드 하나를 잠시 사용할 건데, 이 메서드는 `Rng`가 스코프 내에 있어야 사용할 수 있습니다. 기본적인 아이디어는 이것입니다. 메서드들은 '특성'이라고 불리는 무언가 위에 정의됩니다. 그리고 이 메서드가 동작하기 위해서는, 그 특성이 스코프 내에 있어야 합니다. 더 자세한 내용이 필요하면 [특성][traits] 절을 읽어 주세요.


[traits]: traits.html

중간쯤에 우리가 추가한 또 다른 두 줄이 있습니다.

```rust,ignore
let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);
```

난수 발생기의 사본을 하나 얻기 위해 `rand::thread_rng()` 함수를 사용했습니다. 이 난수 발생기는 우리가 현재 실행하고 있는 특정한 [스레드][concurrency]에 대해 하나씩 존재합니다. 위에서 `use rand::Rng`를 적었기 때문에, `gen_range()` 메서드를 사용할 수 있습니다. 이 메서드는 두 개의 인자를 받아서, 그 사이의 수를 생성합니다. 이 메서드는 하한값은 포함하지만, 상한값은 포함하지 않습니다. 따라서 우리는 1부터 100 사이의 수를 생성하기 위해 `1`과 `101`을 사용해야 합니다.

[concurrency]: concurrency.html

두 번째 줄은 단지 비밀수를 출력합니다. 이 부분은 프로그램을 개발하는 동안 테스트하기가 쉬워지기 때문에 쓸모가 있습니다. 그러나, 최종본에서는 이 부분을 삭제할 것입니다. 시작할 때 답을 출력해 버리면 게임이 되지 않으니까요!

새 프로그램을 몇 번 시험해 봅시다.

```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 7
Please input your guess.
4
You guessed: 4
$ cargo run
Running `target/debug/guessing_game`
Guess the number!
The secret number is: 83
Please input your guess.
5
You guessed: 5
```

잘 되는군요! 다음으로는 우리의 추측과 비밀수를 비교해 봅시다.

# 추측 비교하기

이제 사용자의 입력을 받았으니, 우리의 추측을 난수와 비교해 봅시다. 다음이 그 단계이지만, 아직 잘 작동하컴파일되지는 않습니다.

```rust,ignore
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
}
```

새로운 것들이 약간 들어가 있군요. 그 첫번째는 또 다른 `use`입니다. `std::cmp::Ordering`이라는 타입 하나를 스코프 안으로 가져왔습니다. 그 다음은 아래쪽에서 그걸 사용하고 있는 다섯 줄의 새 라인입니다.

```rust,ignore
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
```

`cmp()` 메서드는 비교될 수 있는 모든 것에서 호출이 가능합니다. 그리고 이 메서드는 여러분이 비교하고자 하는 어떤 것의 레퍼런스를 취합니다. 또 이 메서드는 우리가 앞에서 `use`한 `Ordering` 타입을 반환합니다. 우리는 `Ordering` 중에서 정확히 어떤 것인지를 확실히 알아내기 위해서 [`match`][match] 구문을 사용합니다. `Ordering`은 [`enum`][enum]입니다. 그리고 enum은 열거형(enumeration)의 준말이고, 다음과 같이 생겼습니다.

```rust
enum Foo {
Bar,
Baz,
}
```

[match]: match.html
[enum]: enums.html

이 정의에서, `Foo` 타임의 어떤 것은 `Foo::Bar` 또는 `Foo::Baz`가 될 수 있습니다. `::`는 특정한 `enum` 변형을 위한 네임스페이스를 나타내는 용도입니다.

[`Ordering`][ordering] enum은 `Less`와 `Equal`, `Greater`의 세 가지 변형을 가지고 있습니다. `match` 구문은 어떤 타입의 어떤 값을 취해서, 가능한 값들 각각에 대해서 '가지'를 만들도록 합니다. 세 가지 종류의 `Ordering`이 있기 때문에, 가지도 세 갈래입니다.

```rust,ignore
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
```

[ordering]: ../std/cmp/enum.Ordering.html

만약 `Less`라면 우리는 `Too small!`을 출력합니다. 만약 `Greater`라면 `Too big`을 출력합니다. 그리고 `Equal`일 때는 `You win`을 출력합니다. `match`는 정말로 유용하며 Rust에서 자주 사용합니다.

그렇지만 아직 잘 동작하컴파일되지 않는다고 언급했었죠. 시험해 봅시다.

```bash
$ cargo build
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
src/main.rs:28:21: 28:35 error: mismatched types:
expected `&collections::string::String`,
found `&_`
(expected struct `collections::string::String`,
found integral variable) [E0308]
src/main.rs:28 match guess.cmp(&secret_number) {
^~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `guessing_game`.
```

휴! 큰 에러입니다. 핵심적인 것은 우리가 '타입 불일치(mismatched types)'를 갖고 있다는 점입니다. Rust는 강력한 정적 타입 시스템을 가지고 있습니다. 하지만 Rust는 동시에 타입 추론 기능도 가지고 있습니다. 우리가 `let guess = String::new()`라고 썼을 때, Rust는 `guess`가 반드시 `String`이 되어야 한다는 것을 추론해낼 수 있습니다. 그래서 Rust는 우리에게 타입을 적으라고 하지 않습니다. 그리고 우리의 `secret_number`에 대해서, 1부터 100까지의 수를 저장할 수 있는 타입은 여러 개 존재합니다. 32비트 수인 `i32`나, 부호 없는 32비트 정수형인 `u32`나, 64비트 정수형인 `i64` 등이 있죠. 여기까지는 별로 문제가 없습니다. 그래서 Rust는 기본적으로 `i32`를 사용합니다. 그러나 여기서, Rust는 어떻게 `guess`와 `secret number`를 비교할 수 있는지 알지 못합니다. 그들은 서로 같은 타입이어야 합니다. 궁극적으로는, 입력으로 읽어들인 `String`을 실제 수 타입으로 변환해야만 서로 비교할 수 있습니다. 다음의 세 줄을 추가하여 그렇게 할 수 있습니다.


```rust,ignore
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = guess.trim().parse()
.ok()
.expect("Please type a number!");

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
}
```

새로 추가한 세 줄은 다음과 같습니다.

```rust,ignore
let guess: u32 = guess.trim().parse()
.ok()
.expect("Please type a number!");
```

잠깐, 우리 이미 `guess`를 갖고 있지 않았나요? 그랬습니다. 하지만 Rust는 새 `guess`로 이전 것을 '가리기'를 허용합니다. 이 기능은 `guess`가 `String`으로 시작했지만, 그것을 `u32`로 변경하고 싶은 바로 이러한 상황에 자주 사용됩니다. 가리기 기능 덕분에 우리는 `guess_str`과 `guess`같은 서로 겹치지 않는 이름을 지어내는 대신, `guess`라는 이름을 다시 사용할 수 있습니다.


우리는 `guess`를 이전에 썼던 뭔가와 비슷한 표현식에 결합합니다.

```rust,ignore
guess.trim().parse()
```

`ok().expect()`의 호출에 이어, 여기서의 `guess`는 이전에 인풋으로 받았던 `String`을 저장해둔 `guess`를 참조합니다. `String`의 `trim()` 메서드는 앞, 뒤의 모든 띄어쓰기 및 빈칸을 제거합니다.
이것이 중요한 이유는, 우리가 `read_line()`을 만족시키기 위해 'return' 키를 눌렀기 때문입니다. 만약 우리가 `5`를 입력하고 'return'을 누르면, `guess`의 값이 `5¶
`이 된다는 뜻입니다. `¶
`은 '다음 줄'(Enter키)을 의미합니다. `trim()`을 실행해서 이것을 제거해주고, 우리가 입력한 `5`를 그대로 남겨줍니다. [문자열의 `parse()` 메서드][parse]는 문자열을 일종의 숫자로 해석해줍니다. 이것은 여러 가지 타입의 숫자로 해석할 수 있기 때문에, 우리는 Rust에게 우리가 원하는 정확한 타입에 대한 힌트를 줄 필요가 있습니다. 이렇게요: `let guess: u32`. `guess` 뒤의 콜론(`:`)은 Rust에게 중요한 힌트를 제공합니다.

[parse]: ../std/primitive.str.html#method.parse
[number]: primitive-types.html#numeric-types

`read_line()` 때처럼, `parse()` 메서드는 오류가 일어날 수 있습니다. 만약 문자열에 `A👍%` 같은 것들이 포함된다면 어떨까요? 숫자로 해석할 수 없겠죠. 때문에 우리는 `read_line()` 때 했던 일들을 해주어야 합니다. 오류 처리를 위한 `ok()` 와 `expect()` 말이에요 .

한번 실행해봅시다!

```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 58
Please input your guess.
76
You guessed: 76
Too big!
```

훌륭하네요! 제가 넣은 숫자 앞에 공백을 추가했는데도, 76으로 잘 처리하고 있습니다. 프로그램을 몇 번 실행해보고, 여러가지 숫자들을 넣어 시험해보세요.

게임 동작의 대부분을 완성했지만, 아직 한 가지 일이 남아있습니다.
`loop`를 추가해보도록 하죠!

# 루핑

`loop` 키워드는 무한 루프를 제공합니다. 사용해보면:

```rust,ignore
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = guess.trim().parse()
.ok()
.expect("Please type a number!");

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
}
}
}
```

다음과 같습니다. 그런데 잠깐, 무한 루프요? . `parse()`에서 했던 말들 기억나시나요?
숫자가 아닌 추측들이 주어지면, 에러 처리로 인해 우린 곧바로 프로그램이 `return` 되고 종료됩니다.
직접 보여드리죠:

```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 59
Please input your guess.
45
You guessed: 45
Too small!
Please input your guess.
60
You guessed: 60
Too big!
Please input your guess.
59
You guessed: 59
You win!
Please input your guess.
quit
thread '
' panicked at 'Please type a number!'
```

하! 숫자가 아닌 `quit` 입력이 말 그대로 프로그램을 종료시켰군요.
이것은 단지 일부일 뿐입니다. 첫째로, 우리가 추측을 성공시켰을 때도 게임을 종료해야하죠:

```rust,ignore
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = guess.trim().parse()
.ok()
.expect("Please type a number!");

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
```

`break`를 `You win!` 줄 아래에 추가함으로써, 추측이 성공했을 때 루프를 탈출할 수 있게 됩니다.
루프가 돌고 있다는 것은 `main()` 이 남아있어 프로그램이 계속 존재한다는 것을 뜻합니다.
하나만 더 해보죠. 누군가가 숫자가 아닌 추측을 입력했을 때 종료하는 대신 그냥 그것을 무시하고 싶습니다.
이렇게 할 수 있겠죠:

```rust,ignore
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

println!("The secret number is: {}", secret_number);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
```

바뀐 라인은 다음과 같습니다:

```rust,ignore
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
```

`ok().expect()` 를 `match` 문으로 전환하면서, 우리는 단순한 '충돌 방지' 에서'실질적 에러 핸들'이 가능하게 되었습니다. `parse()`에 의해 리턴된 `Result`는 `Ordering` 때와 같이 열거형입니다. 그러나 이번 경우엔, 각 라인이 관련이 있는 어떤 정보들을 지니고 있습니다: `Ok`는 성공, `Err`는 실패를 나타내죠. 더 구체적으로, 숫자라면 성공적, 다른 타입이라면 에러입니다. `match` 안의 `Ok(num)`은 `Ok`의 내부 값을 `num`이라는 이름에 담습니다. 그런 다음 곧바로 그것을 우변에서 리턴합니다. `Err`의 경우 어떤 종류의 에러이든지 상관하지 않을 때 이름 대신 `_`를 쓸 수 있습니다. 에러를 무시하고, `continue`를 실행해 다음 `loop`로 건너뛸 수 있게 해줍니다.

제대로 작동할 것 같네요! 실행시키면:

```bash
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 61
Please input your guess.
10
You guessed: 10
Too small!
Please input your guess.
99
You guessed: 99
Too big!
Please input your guess.
foo
Please input your guess.
61
You guessed: 61
You win!
```

멋집니다! 사소한 한 가지만 더 고친다면 추리 게임이 완성됩니다. 뭔지 아시겠나요? 그렇습니다. 우리의 비밀 숫자를 내보이고 싶지 않겠죠. 테스트에는 도움이 되었지만, 게임을 망치고 있습니다.
최종 완성본입니다:

```rust,ignore
extern crate rand;

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {
println!("Guess the number!");

let secret_number = rand::thread_rng().gen_range(1, 101);

loop {
println!("Please input your guess.");

let mut guess = String::new();

io::stdin().read_line(&mut guess)
.ok()
.expect("failed to read line");

let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};

println!("You guessed: {}", guess);

match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
```

# 완료!

추리 게임을 성공적으로 만들었습니다! 축하드립니다!

이 첫 번째 프로젝트는 많은 것을 다루었습니다: `let`, `match`, 메소드, 연결된 함수, 외부 크레이트 사용하기 등등. 다음 프로젝트에서는 더 많은 것을 다룰 것입니다.
hello-cargo
# 2.3. 안녕, 카고! (Hello, Cargo!) - 100%

[Cargo][cratesio]는 러스트인(Rustaceans)들에게 그들의 Rust 프로젝트 관리를 도와주는 도구입니다. Cargo는 pre-1.0 상태이고, 그렇기 때문에 아직 개발중입니다. 하지만, 이미 많은 Rust 프로젝트에 사용하기에 충분히 좋기 때문에, Rust 프로젝트를 시작할때 Cargo를 사용할 것이라고 가정합니다.

[cratesio]: http://doc.crates.io

Cargo는 세가지를 관리합니다. 여러분의 코드를 빌드하고, 여러분의 코드가 필요로하는 종속성(dependencies)들을 다운로드하고, 그 종속성들을 빌드합니다. 처음에는, 여러분의 프로그램은 어떠한 종속성도 갖지 않기 때문에, 우리는 오직 이 놈의 기능의 첫번째 부분만 사용합니다. 결과적으로 우리는 더(종속성등을) 추가할것입니다. Cargo를 사용하기 시작했기에 이러한 작업은 더욱 쉬워질것입니다.

여러분이 Rust를 공식 인스톨러를 통해 설치했다면, Cargo 또한 가지고 있을 것입니다. Rust를 몇몇 다른 방식으로 설치했다면, 설치에 관한 좀더 자세한 사항은 [check the Cargo README][cargoreadme]를 참고하세요.

[cargoreadme]: https://github.com/rust-lang/cargo#installing-cargo-from-nightlies

## Cargo로 변환하기 (Converting to Cargo)

Hello World를 Cargo로 변환해 봅시다.

여러분의 프로젝트를 Cargo화(-ify) 하려면, 가지가 필요합니다. `Cargo.toml` 설정 파일을 만들고, 소스 파일을 적당한 위치에 가져다 둡니다. and get rid of the old executable (`main.exe` on Windows, `main` everywhere else). 시작해 볼까요?

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

실행파일을 생성할것이기에 retain `main.rs`를 사용했습니다 as the source filename. 만약 여러분이 라이브러리를 생성하고 싶으시면 `lib.rs`를 사용해야합니다. 이 관습은 Cargo가 우리의 프로젝트를 성공적으로 컴파일하는데 필요로 하사용되지만, 원한다면 overridden 할 수 있습니다. 프로그램 엔트리를 사용자 파일로 하시고자 하신다면 TOML파일의 [`[lib]` or `[[bin]]`][crates-custom] 섹션에 설정하실수 있습니다.

[crates-custom]: http://doc.crates.io/manifest.html#configuring-a-target

Cargo는 여러분의 소스 파일들이 `src` 디렉토리에 있을거라고 생각합니다. 그 외에 README, 라이선스 정보, 코드와 관련 없는 것들은 최상위에 두셔도 됩니다. Cargo는 여러분의 프로젝트를 깔끔하게 유지하는데 도움을 줍니다. 여기에 프로젝트의 모든 것이 위치합니다.

이어서, 설정 파일을 보겠습니다.

```bash
$ editor Cargo.toml
```

이름에 유의하세요! 대문자 `C` 이어야 합니다.

다음을 입력하세요.

```toml
[package]

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

이 파일은 [TOML][toml] 형식으로 작성되었습니다. TOML은 INI와 비슷하지만, 몇몇 추가적인 장점들을 가지고 있습니다. TOML 문서를 살펴보면,

> TOML은 명백한 의미 덕분에 쉽게 읽을 수 있는 최소한의 설정 파일 형식을 지향합니다. TOML은 해쉬테이블로 매칭이 명확하게되도록 디자인되어있습니다.
> TOML은 다양한 언어의 데이터구조로 쉽게 변환될수 있습니다.

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

파일이 제대로 설정되었프로젝트의 루트 디렉토리에 있다면 우리는 이제 빌드를 할 준비가 되었습니다! 실행해봅시다.

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

짜잔! 여러분들은 `cargo build`를 통해 프로젝트를 빌드했고, `./target/debug/hello_world`로 실행했습니다. `cargo run`으로 한번에 할 수도 있습니다.

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

우리는 이 프로젝트를 재빌드하지 않았음에 주목해주세요. Cargo는 우리가 소스파일에 어떠한 수정도 하지 않았음을 자동적으로 인식하고, 빌드 없이 바이너리를 실행했습니다. 만약 우리가 수정을 했다면 재빌드와 실행의 두가지 결과를 보게될것입니다.

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

이것은 우리에게 `rustc`를 단순하게 사용하는 것 이상을 가져다 주진 않지만, 나중을 생각해봅시다. 우리 프로젝트가 더 복잡해진다면, 프로젝트의 모든 부분이 정상적으로 컴파일되기 위해서 더 많은 작업을 해야 할 것입니다. Cargo를 이용한다면 프로젝트가 커지더라도, 단지 `cargo build`를 실행하는 것만으로도 올바르게 동작할 것입니다.

여러분의 프로젝트를 배포할 준비가 다 되었다면, `cargo build --release` 커맨드를 이용하여 여러분의 프로젝트를 컴파일하고 최적화할수 있습니다.

추가로, Cargo가 `Cargo.lock`라는 새로운 파일을 생성한다는 것을 알 수 있을 것입니다.

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

`Cargo.lock` 파일은 Cargo에서 여러분의 애플리케이션의 종속성을 추적하는데 사용됩니다. 현재 우리는 아무런 종속성을 가지고 있지 않기 때문에 많은 내용이 없습니다. 여러분은 이 파일을 건드릴 필요가 없으며, Cargo에서 처리하도록 놔두면 됩니다.

끝입니다! 우리들은 Cargo를 이용해 `hello_world`를 성공적으로 빌드했습니다. 이번 프로그램은 단순하지만, 앞으로의 Rust 개발 경력에 있어 실제로 자주 사용하게 될 도구들을 사용하고 있습니다. 앞으로 대부분의 Rust 프로젝트들을 이와 같은 과정으로 시작하게 될 것입니다.

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

## 새 프로젝트(A New Project)

새로운 프로젝트를 시작하기 위해 매번 모든 절차를 진행해야 하지 마세요! Cargo는 여러분이 즉시 개발을 시작하도록 프로젝트 디렉토리의 기본 골격을 만드는 능력을 가지고 있습니다.

Cargo를 이용해 새 프로젝트를 시작하려면, `cargo new`를 이용하세요.

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

우리의 목적은 라이브러리와는 다르게 실행할 수 있는 응용 프로그램을 곧바로 얻기 위함이기 때문에 `--bin`을 전달했습니다. 실행 가능한 것들은 주로 ‘바이너리(binaries).’라고합니다. (유닉스 시스템이라면 `/usr/bin`에 있는 것들이죠.)

Cargo가 무엇을 만들었는지 확인해볼까요?

```bash
$ cd hello_world
$ tree .
.
├── Cargo.toml
└── src
└── main.rs

1 directory, 2 files
```

`tree` 명령어가 없다면, 배포판 패키지 관리자에서 받을 수 있습니다. 꼭 필요한 것은 아니지만, 확실히 도움은 됩니다.

이것이 시작하기에 필요한 전부입니다. 우선, `Cargo.toml`을 확인해봅시다.

```toml
[package]

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

Cargo는 여러분이 넘겨주는 인자들과 `git`의 전역 설정을 토대로 합당한 기본값으로 이 파일을 생성합니다. 그리고 `hello_world` 디렉토리를 `git` 레파지터리로 초기화합니다.

`src/main.rs`을 살펴봅시다.

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

Cargo는 여러분을 위해 "Hello World!"를 생성했고, 여러분은 코딩을 시작할 준비가 되었습니다. Cargo는 더 세부적인 기능을 다루고 있는 [가이드][guide]를 자체적으로 가지고 있습니다.

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

이제 필요한 툴을 다 갖췄으면 Rust 언어에 대해 더 배워볼 시간입니다. 이런 기본들은 여러분이 Rust와 함께 하는 시간동안 많은 도움을 줄 것입니다.

두 가지 선택이 있습니다: 곧바로 ‘[Rust 배우기][learnrust]’로 프로젝트에 뛰어들거나 ‘[문법과 의미][syntax]’를 통해 밑바닥부터 배울 수도 있습니다. 경험이 풍부한 시스템 프로그래머는 아마 ‘Rust 배우기’ 쪽이, 동적 언어 세계에서 오신 분들은 어느 쪽이나 상관없을 테지요. 각자 자기 방식대로 배우는 겁니다! 여러분에게 맞는 쪽을 택하세요.

[learnrust]: learn-rust.htmlmd
[syntax]: syntax-and-semantics.htmlmd
hello-world
# 2.2. 안녕, 세상아! (Hello, world!) - 100%

이제 Rust를 설치했으니, 여러분의 첫번째 Rust 프로그램을 작성해볼까요? 전통적으로, 새로운 언어로 만드는 첫번째 프로그램은 화면에 “Hello, world!” 텍스트를 출력하는 것입니다. 단순한 프로그램으로 시작하는 것이 좋은 이유는, 당신의 컴파일러가 설치되었을 뿐만 아니라 제대로 작동하는지를 검증할 수 있다는 점입니다. 화면에 정보를 출력하는 일은 흔하기도 하구요.

처음으로 해야할 일은 여러분의 코드가 들어갈 파일을 만드는 것입니다. 저는 홈 디렉토리에 `projects` 디렉토리를 만들고, 거기에 저의 모든 프로젝트를 보관하길 선호하죠. 하지만 Rust는 여러분의 코드가 어디에 있던지 신경쓰지 않습니다.

먼저 이 얘기를 여러분에게 드려야 할 것 같네요. 이 가이드는 기본적으로 여러분이 커맨드 라인에 어느정도는 친숙하다고 가정합니다. Rust 자체는 여러분이 사용할 에디터나 여러분의 코드의 위치에 대해서 어떠한 것도 요구하지 않습니다. 만약 커맨드 라인보다 IDE사용에 더 친숙하다면 [SolidOak][solidoak]를 비롯한 여러분이 선호하시는 IDE의 플러그인을 확인해보시길 바랍니다. 여러 커뮤니티에 의해 개발중인, 다양한 퀄리티의 수많은 종류의 플러그인들이 존재합니다. 또한 Rust 팀에서는 [여러 에디터들을 위한 플러그인들][plugins]을 제공합니다. 에디터나 IDE를 어떻게 설정할지는 본 튜토리얼의 범위를 벗어나므로, 여러분의 환경에 알맞은 문서들을 참고하세요.

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

이러한 전제 하에, 우리의 프로젝트 디렉토리 내부에 디렉토리를 만들어 봅시다.

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

만약 당신이 Windows에서 작업중이고 PowerShell을 쓰고 있지 않다면, `~`는 동작하지 않을 것입니다. 쉘에 대한 더 자세한 내용은 해당 문서를 참고하세요.

자! 그럼 새로운 소스파일을 생성해 보겠습니다. 이 파일을 `main.rs`로 이름 짓도록 하겠습니다. Rust 파일은 항상 `.rs` 확장자로 끝납니다. 파일명에 둘 이상의 단어를 사용한다면, 밑줄(underscore)을 사용하세요. `helloworld.rs`가 아니라 `hello_world.rs` 라는 식으로요.

이제 파일이 열렸으니, 다음을 입력하세요.

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

파일을 저장하고, 터미널 창에 다음을 입력하세요.

```bash
$ rustc main.rs
$ ./main # or main.exe on Windows
Hello, world!
```

성공입니다! 무슨 일이 일어난건지 좀 더 자세히 살펴보죠.

```rust
fn main() {

}
```

Rust에서 이러한 라인들은 _함수(function)_를 정의합니다. `main` 함수는 특별합니다. 모든 Rust 프로그램의 시작입니다. 첫번째 라인은 "아무런 인자도 취하지 않고, 아무것도 반환하지 않는 `main`이라는 함수를 정의하겠다"는 의미입니다. 만약 인자가 존재한다면, 괄호(`(`와 `)`) 사이에 위치하게 됩니다. 또한 이 함수가 어떤것도 반환하지 않기에, 반환 타입 자체를 생략할 수 있는거죠. 나중에 다시 살펴보겠습니다.

또 한가지 주의해야 할 점은, 함수는 중괄호(`{`와 `}`)에 감싸져 있다는 점입니다. Rust는 모든 함수 몸체(function body)가 중괄호로 감싸질 것을 요구합니다. 또한 함수 선언과 여는 중괄호는 같은 라인에 위치하고, 그 사이에는 하나의 공백이 있는 것이 좋은 스타일입니다.

다음은 이 라인입니다.

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

이 라인은 우리의 작은 프로그램에서 하는 모든 작업을 담당하죠. 몇 가지 중요한 세부 사항들이 있습니다. 첫번째는 탭이 아닌 네개의 공백으로 들여쓰기를 한다는 것입니다. 각자 선택한 에디터에서 탭 키를 누르면 네 개의 공백을 삽입하도록 설정해주세요. 우리는 [다양한 편집기를 위한 샘플 설정][configs]을 제공합니다.

[configs]: https://github.com/rust-lang/rust/tree/master/src/etc/CONFIGS.md

두번째 포인트는 `println!()` 부분입니다. 이는 Rust [매크로][macro]의 호출이고, Rust에서 메타프로그래밍(metaprogramming)이 이루어지는 방법입니다. 만약 함수였다면, `println()`이라고 적었을 것입니다. 당장은 이 차이에 대하 걱정할 필요가 없습니다. `!`가 있다면, 보통 함수 대신에 매크로를 호출하는 것이라고만 알고있으세요. Rust는 `println!`을 함수가 아닌 매크로로 구현하는데는 몇 가지 합당한 이유들이 있지만, 그 내용은 고급 주제입니다. 마지막으로 한 가지 언급하자면, Rust의 매크로는 C의 매크로와 완전히 다릅니다. 매크로를 사용한다고 겁먹지 마세요. 세부적인 내용은 차차 살펴볼테니, 지금으로선 그냥 우리를 믿어주길 바랍니다.

[macro]: macros.html

다음으로, `"Hello, world!"`는 ‘문자열(string)’입니다. 문자열은 시스템 프로그래밍 언어에서는 대단히 복잡한 주제이고, 이는 ‘정적 할당된(statically allocated)’ 문자열입니다. 만약 메모리 할당에 대해 좀 더 알고 싶다면 [스택과 힙][allocation] 항목을 참고하시면 되지만, 별로 그러고 싶지 않다면 지금 당장으로선 그럴 필요는 없습니다. 아무튼, 문자열을 화면에 출력하는 `println!`의 인자로 이 문자열을 전달한거에요. 어려운 내용은 아닐거라 믿습니다!

[allocation]: the-stack-and-the-heap.html

마지막으로, 라인은 세미콜론(`;`)으로 끝납니다. Rust는 [‘표현식 지향(’ 언어][expression -oriented)’ 언어입니다 language]. 이는 대부분이 선언문(statement)보다는 표현식(expression)임을 의미합니다. `;`는 이 표현식이 끝났고, 다음 표현식이 시작할 준비가 되었음을 알리기 위해 사용됩니다. 대부분의 Rust 코드 라인은 `;`로 끝납니다.

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

드디어, 우리 프로그램을 컴파일(compiling)하고 실행(running) 할 시간이 왔네요. `rustc` 컴파일러에 소스 파일의 이름을 넘김으로서 컴파일할 수 있습니다.

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

C와 C++을 알고있다면 `gcc` 또는 `clang`과 비슷할 것입니다. Rust는 바이너리 실행파일을 출력하죠. `ls`를 입력해 확인해보세요.

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

또는 Windows에서는 다음과 같을거구요.

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

이제 두 파일이 존재합니다. `.rs` 확장자를 가진 소스 코드와 실행 가능 파일 (Windows에서는`main.exe`, 나머지에서는 `main`) 입니다.

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

이 작업은 터미널에 `Hello, world!` 텍스트를 출력 할 것입니다.

만약 Ruby, Python, 또는 JavaScript와 같은 동적 언어 백그라운드를 갖고 계시다면, 이 두 단계가 나누어져 있는 것에 익숙하지 않으실 수 있을거에요. Rust는 ‘AOT 컴파일되는 언어(ahead-of-time compiled language)’ 입니다. 즉, 여러분이 프로그램을 컴파일 한 뒤 다른 누군가에게 넘긴다면, 그 사람의 컴퓨터엔 Rust가 설치되어 있을 필요가 없다는 뜻이죠. 여러분이 누군가에게 `.rb` 또는 `.py` 또는 `.js` 파일을 전달한다면, 그들은 Ruby/Python/JavaScript 구현이 설치되어 있어야 하겠지만, 대신 하나의 명령어 만으로 컴파일과 실행을 동시에 할 수 있겠죠. 결국 언어 설계에서 모든 것은 등가교환_tradeoff_이고, Rust는 결정을 내린 것 뿐입니다.

축하드립니다! 여러분은 방금 정식으로 Rust 프로그램을 작성하셨고, 이는 Rust 프로그래머가 되신 것을 의미하죠! 환영합니다. 🎊🎉👍

다음으로, 실제 개발환경에서 사용되어지는 Cargo라는 툴에 대해 소개하도록 하겠습니다. 간단한 작업을 위해서는 단순히 `rustc`만 사용하는 것도 괜찮은 선택이겠죠. 하지만 여러분의 프로젝트 규모가 커짐에 따라, 그것이 제공하는 다양한 옵션들을 관리하거나 여러분의 코드를 다른 사람들과 공유함에 있어서 여러가지 편리한 기능들을 제공할 무언가를 필요로 하게 될 것입니다.
installing-rust
# 2.1. Rust 설치하기 (Installing Rust) - 10095%

Rust를 사용하기 위해서 가장 먼저 해야할 일은 Rust를 설치하는 것입니다. 수많은 방법들이 있지만, 가장 쉬운 방법은 `rustup` 스크립트를 사용하는 것입니다. 만약 당신의 리눅스나 맥을 사용중이라면, 필요한건 다음의 스크립트가 전부입니다.

> 각주: `$` 기호는 입력할 필요 없어요. 각 명령의 시작을 뜻합니다. 웹에서 볼 수 있는 대다수의 튜토리얼과 예제들에서 다음의 관습을 따르는 것을 볼 수 있습니다. 일반 사용자로 실행하는 명령은 `$`, 관리자로 실행해야 하는 명령은 `#`.

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

`curl | sh` 사용의 [잠재적 위험][insecurity]이 걱정된다면, 설치를 두 단계로 나눈 버전을 사용하고, 설치 스크립트를 검사하세요.

```bash
$ curl -f -L https://static.rust-lang.org/rustup.sh -O
$ sh rustup.sh
```

[insecurity]: http://curlpipesh.tumblr.com

만약 당신 컴퓨터의 운영체제가 Windows 라면, 적합한 [인스톨러][install-page]를 다운로드 받으세요.
**NOTE:** By default, the Windows installer will not add Rust to the %PATH%
system variable. If this is the only version of Rust you are installing and you
want to be able to run it from the command line, click on "Advanced" on the
install dialog and on the "Product Features" page ensure "Add to PATH" is
installed on the local hard drive.


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

## 삭제하기 (Uninstalling)

더 이상 Rust를 원하지 않는다고 판단하신다면, 슬프지만, 괜찮아요. 어떤 프로그래밍 언어가 모두에게 최고가 될 수는 없죠. 그냥 설치 제거 스크립트를 실행하세요.

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

Windows 인스톨러를 사용한다면, 그냥 `.msi`를 재실행하면, 언인스톨 옵션을 보여줄 것입니다.

## That disclaimer we promised

어떤 사람들은 `curl | sh` 커맨드의 사용에 대해 민감하게 반응할지 모르고, 그건 정당한 반응이에요.
기본적으로 여러분이 이 커맨드를 실행한다는 것은 Rust에 기여를 하는 사람들이 여러분의 컴퓨터를 해킹하거나, 그 외의 나쁜 행위를 하지 않을것이라 믿는다는 것을 의미합니다. 아마 실제로도 그럴거에요! 다만 만약 여러분이 이 커맨드의 사용을 원치 않는다면 [소스 코드로부터 Rust 빌딩하기][from-source], 또는 [공식 바이너리 설치][install page] 문서를 참고하기를 권합니다.

[from-source]: https://github.com/rust-lang/rust#building-from-source

## Platform support

오! 공식적으로 지원되는 플랫폼이 무엇인지도 말씀드려야겠죠.

* Windows (7, 8, Server 2008 R2)
* Linux (2.6.18 또는 이후, 다양한 배포판), x86과 x86-64
* OSX 10.7 (Lion) 또는 이상, x86과 x86-64

우리는 Rust를 위의 플랫폼들에서 광범위하게 테스트했고, 그 테스트들은 안드로이드를 비롯한 다른 몇몇 플랫폼에서도 이루어졌습니다. 하지만 위의 플랫폼들에서 가장 많은 테스팅이 이루어졌기 때문에, 그 곳에서 (Rust가) 제대로 작동할 확률이 가장 높을 것입니다.

마지막으로, Windows에 대해서 언급하겠습니다. Rust는 Windows를 중요 릴리즈 플랫폼으로 고려하고 있지만, 솔직히 말하면, Windows환경은 Linux/OS X와는 꽤 다르다고 할 수 있죠. 일단은 열심히 작업중입니다! 만약 정상적으로 작동하지 않는 것이 있다면 버그일테니, 그런 일이 발생한다면 부디 알려주세요. 모든 커밋은 다른 플랫폼들과 동일하게 Windows상에서도 테스트됩니다.

## After installation

Rust를 설치했다면, 쉘을 열어서 다음을 입력하세요.

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

버전 숫자, 커밋 해시, 커밋 날짜를 볼 수 있을겁니다. 1.04.0 버전을 설치했다면, 다음과 같이 보일 것입니다.

```bash
rustc 1.02.0 (a59de37e9082e47636 2015-05-18-03)
```

위처럼 나왔다면, Rust를 성공적으로 설치하셨습니다. 축하드립니다!

If you didn'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.

인스톨러은 여러분이 이 문서를 오프라인에서도 볼수 있도록 여러분의 로컬 컴퓨터에도 설치할거에요.
유닉스 시스템에서는 `/usr/local/share/doc/rust`, 윈도우즈에서는 러스트가 설치된 경로 밑의 `share/doc` 디렉토리에서 이 문서를 찾으실 수 있습니다.

그렇지 않다면, 여러분이 도움을 얻을 수 있는 다양한 장소가 있습니다. 가장 쉬운방법은 [Mibbit][mibbit]등을 통해서 [irc.mozilla.org 서버의 #rust IRC 채널][irc]에 접속하는 방법입니다. 링크를 클릭하시면 다른 많은 러스트 사용자들과 대화를 나누실수 있고, 저희들이 도움을 드릴 수도 있습니다. [사용자 포럼][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
lifetimes
# 5.109. 수명 (Lifetimes) - 1090%

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

* 핵심 개념인 [소유권][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<'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]: 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]를 사용할 때에도 명시적 수명이 필요합니다.

```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(&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
loops
# 5.6. 반복 (Loops) - 50%

Rust currently provides three approaches to performing some kind of iterative activity. They are: `loop`, `while` and `for`. Each approach has its own set of uses.

## loop

The infinite `loop` is the simplest form of loop available in Rust. Using the keyword `loop`, Rust provides a way to loop indefinitely until some terminating statement is reached. Rust's infinite `loop`s look like this:

```rust,ignore
loop {
println!("Loop forever!");
}
```

## while

러스트에는 `while` 반복문 역시 존재합니다. 다음과 같은 모습이죠.

```rust
let mut x = 5; // mut x: i32
let mut done = false; // mut done: bool

while !done {
x += x - 3;

println!("{}", x);

if x % 5 == 0 {
done = true;
}
}
```

`while` 반복문은 당신이 얼마나 많은 횟수를 반복해야할지 확신이 없을 때 좋은 선택지입니다.

무한 루프가 필요할 때, 다음과 같이 쓰고 싶은 마음이 들겠죠.

```rust,ignore
while true {
```

하지만, 이 경우를 처리하는데에는 `loop`가 더 어울립니다.

```rust,ignore
loop {
```

이렇게 생성된 반복문은 항상 반복할 것이기 때문에, 러스트의 제어흐름 분석은 이러한 반복문을 `while true`와 다르게 취급합니다. 일반적으로, 우리가 컴파일러에게 더 많은 정보를 줄수록 컴파일러는 더 나은 보안과 최적화를 할 수 있기 때문에, 만약 무한 루프를 만들 생각이라면 `loop`를 사용하는게 좋습니다.

## for

`for` 반복문은 어떤 내용을 특정 회수만큼 반복하고 싶을 때 사용합니다. 하지만, 러스트에서의 `for` 반복문은 다른 시스템 언어에서와는 약간 다르게 작동합니다. 러스트의 `for` 반복문은 "C-스타일"의 `for` 반복문처럼 생기지 않았습니다.

```c
for (x = 0; x < 10; x++) {
printf( "%d¶
", x );
}
```

그보다는, 이런 식이죠.

```rust
for x in 0..10 {
println!("{}", x); // x: i32
}
```

약간 더 추상적으로 나타내자면,

```ignore
for var in expression {
code
}
```

이 때의 expression은 [반복자][iterator]입니다. 반복자는 일련의 원소들을 반환하는데, 이 때 각각의 원소가 반복문의 한 회차 반복에 해당합니다. 해당 원소의 값은 `var`라는 이름에 바인딩되고, 이 바인딩은 반복문의 본문 (위의 예제에서 code 부분) 동안 유효합니다. 본문을 한 번 지나고 나면, 반복자로부터 다음 값을 받아오고, 한 번 더 반복하는 식이죠. 반복자에 더이상 남은 값이 없을 때, for 반복문은 끝이 납니다.

[iterator]: iterators.html

우리의 예제로 돌아가서, `0..10`은 시작점과 끝점을 받은 뒤, 그 사이의 값들을 원소로 갖는 반복자를 반환합니다. 이 때 상한값은 제외되므로, 위의 반복문은 `0`부터 `9`까지 출력하게 됩니다. `10`은 출력되지 않죠.

러스트가 "C-Style" `for` 반복문을 지원하지 않는 것은 의도적입니다. 반복문의 각 인자들을 수동적으로 조작해주는 일은 숙련된 C 개발자들에게조차 복잡하고 에러를 일으키기 쉬운 작업이거든요.

### 열거하기 (Enumerate)

몇번 반복했는지 추적해야하고 싶을 경우엔, `.enumerate()` 함수를 사용하면 됩니다.

#### 범위를 열거하기 (On ranges)

```rust
for (i,j) in (5..10).enumerate() {
println!("i = {} and j = {}", i, j);
}
```

출력

```text
i = 0 and j = 5
i = 1 and j = 6
i = 2 and j = 7
i = 3 and j = 8
i = 4 and j = 9
```

범위 앞뒤로 괄호를 붙혀야 한다는 것을 잊지마세요.

#### 반복자를 열거하기 (On iterators)

```rust
# let lines = "hello¶
world".lines();
for (linenumber, line) in lines.enumerate() {
println!("{}: {}", linenumber, line);
}
```

출력

```text
0: Content of line one
1: Content of line two
2: Content of line three
3: Content of line four
```

## Ending iteration early

Let’s take a look at that `while` loop we had earlier:

```rust
let mut x = 5;
let mut done = false;

while !done {
x += x - 3;

println!("{}", x);

if x % 5 == 0 {
done = true;
}
}
```

We had to keep a dedicated `mut` boolean variable binding, `done`, to know
when we should exit out of the loop. Rust has two keywords to help us with
modifying iteration: `break` and `continue`.

In this case, we can write the loop in a better way with `break`:

```rust
let mut x = 5;

loop {
x += x - 3;

println!("{}", x);

if x % 5 == 0 { break; }
}
```

We now loop forever with `loop` and use `break` to break out early. Issuing an explicit `return` statement will also serve to terminate the loop early.

`continue` is similar, but instead of ending the loop, goes to the next
iteration. This will only print the odd numbers:

```rust
for x in 0..10 {
if x % 2 == 0 { continue; }

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

## Loop labels

You may also encounter situations where you have nested loops and need to
specify which one your `break` or `continue` statement is for. Like most
other languages, by default a `break` or `continue` will apply to innermost
loop. In a situation where you would like to a `break` or `continue` for one
of the outer loops, you can use labels to specify which loop the `break` or
`continue` statement applies to. This will only print when both `x` and `y` are
odd:

```rust
'outer: for x in 0..10 {
'inner: for y in 0..10 {
if x % 2 == 0 { continue 'outer; } // continues the loop over x
if y % 2 == 0 { continue 'inner; } // continues the loop over y
println!("x: {}, y: {}", x, y);
}
}
```
mutability
# 5.110. 가변성 (Mutability) - 99%

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`를 갱신하였죠?

ownership
# 5.87. 소유권 (Ownership) - 100%

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

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

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

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

# 메타

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

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

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

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

# 소유권

러스트에서 [변수 바인딩][bindings]들은 그것들에 바인드 된 자원에 대한 '소유권을 가지고' 있습니다. 이것은 바인딩이 스코프를 벗어나면, 그 변수들에러스트는 바인드 된 리소스가 자유로워진다는 것을 의미합를 해제할 것입니다. 예를 들어보죠:

```rust
fn foo() {
let v = vec![1, 2, 3];
}
```

`v`가 스코프에 들어오면, 새로운 [`Vec`][vect]가 생성됩니다. 또한 이 경우, 그 벡터는 세 개의 원소를 위한 공간을 [힙 영역][heap]에 할당합니다. `foo()`의 끝부분에서 `v`가 스코프를 벗어나게 되면, 러스트는 이 벡터와 관련된 모든 것을 정리합니다. 힙 영역에 할당된 메모리까지 말이죠. 이러한 일은 스코프의 끝부분에서 결정론적으로 일어납니다.

[vect]: ../std/vec/struct.Vec.html
[heap]: the-stack-and-the-heap.html
[bindings]: variable-bindings.html

# 이동 시맨틱

좀 더 미묘한 문제들이 있는데요. 러스트는 어떤 자원에 대해서건 _정확히 하나의_ 바인딩만이 존재할것을 보장합니다. 예를 들어, 우리가 벡터를 하나를 가지고 있을 때, 그 벡터를 다른 바인딩에 할당할 수 있겠죠:

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

let v2 = v;
```

하지만, 이 이후에 우리가 `v`를 사용하려 한다면:

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

let v2 = v;

println!("v[0] is: {}", v[0]);
```

에러가 발생합니다. 이런식으로 말이죠:

```text
error: use of moved value: `v`
println!("v[0] is: {}", v[0]);
^
```

소유권을 가져가는 어떤 함수를 정의한 후, 그 함수에 인자로서 넘긴 무언가를 그 후에 사용하려 할 때도 비슷한 일이 일어납니다:

```rust,ignore
fn take(v: Vec) {
// what happens here isn’t important.
}

let v = vec![1, 2, 3];

take(v);

println!("v[0] is: {}", v[0]);
```

같은 에러죠: '이동된 값의 사용 _use of moved value_'. 우리가 어떤 소유권을 다른 어딘가로 이전시킬 때, 우리는 그것을 '이동시켰다'고 말합니다. 이 작업은 러스트에 의해 알아서 행해지고, 따로 뭘 적을 필요는 없습니다.

## 세부사항

우리가 어떤 바인딩을 이동시킨 후부터는 그 바인딩을 사용할 수 없는 이유는 미묘하지만 중요합니다. 이런 코드를 생각해 보세요:

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

let v2 = v;
```

첫 째 줄은 벡터 객체인 `v`와 거기 담겨 있는 데이터들을 위한 메모리를 할당합니다. 벡터 객체는 [스택][sh]에 저장되고, [힙][sh] 영역에 저장되어 있는 내용물들(`[1, 2, 3]`)을 가리키는 포인터를 포함합니다. 우리가 `v`를 `v2`로 옮기면, `v2`가 사용할 그 포인터의 복사본이 생성됩니다. 다시 말해, 힙 영역에 있는 그 벡터의 내용물들을 가리키는 두 개의 포인터가 존재하는거죠. 이는 데이터 레이스를 발생시킴으로서 러스트의 안전 지침을 침해합니다. 따라서, 러스트는 이동이 일어난 후에는 `v`의 사용을 금지합니다.

[sh]: the-stack-and-the-heap.html

또한, 스택 영역에 실제로 존재하는 복사본은 최적화 과정에서 삭제될 수 있다는 점에 유의하세요. 그렇기 때문에, 실제로는 이러한 시맨틱이 보이는 것만큼 비효율적이지는 않답니다.

## `Copy` 타입

소유권이 다른 바인딩으로 넘어갈 경우 기존의 바인딩을 사용하지 못한다고 했었죠. 하지만, 이러한 행동 양식을 바꾸는 `Copy`라는 [특성_trait_][traits]이 존재합니다. 우리는 특성들에 대해 아직 이야기하지 않았지만, 지금으로서는 특정 타입에 행동 양식을 추가하는 주석같은 존재라고 생각하세요. 예를 들어:

```rust
let v = 1;

let v2 = v;

println!("v is: {}", v);
```

이 경우에, `v`는 `Copy` 특성을 구현한 `i32` 타입입니다. 이동을 할 때와 마찬가지로 우리가 `v2`에 `v`를 할당할 때, 데이터의 복사본이 만들어집니다. 하지만 이동과는 다르게, 그 후에도 우리는 `v`를 사용할 수 있습니다. 이는 `i32`는 다른 곳에 있는 데이터로의 포인터를 가지고 있지 않아서 `i32`의 복사는 완전한 복사를 의미하기 때문에 그렇습니다.

모든 기본 타입은 `Copy` 특성을 구현하고 있고, ´소유권 규칙(ownership rules)´에 따라, 소유권은 이동하지 않습니다. 예를 들어, `i32`와 `bool` 타입은 `Copy` 특성을 구현했기 때문에 다음의 두 코드 조각은 컴파일 됩니다.

```rust
fn main() {
let a = 5;

let _y = double(a);
println!("{}", a);
}

fn double(x: i32) -> i32 {
x * 2
}
```

```rust
fn main() {
let a = true;

let _y = change_truth(a);
println!("{}", a);
}

fn change_truth(x: bool) -> bool {
!x
}
```

`Copy` 특성이 구현되지 않은 타입을 사용했다면, 이동할 수 있는 값을 사용하려고 했기에, 컴파일 오류를 얻을 것입니다.

```text
error: use of moved value: `a`
println!("{}", a);
^
```

당신이 정의한 타입들이 `Copy` 특성을 가지게 하는 방법에 대해선 [특성][traits] 섹션에서 살펴보도록 하겠습니다.

[traits]: traits.html

# 소유권을 넘어서

당연하지만, 만약 우리가 작성한 모든 함수에서 소유권을 반환해야 한다면:

```rust
fn foo(v: Vec) -> Vec {
// do stuff with v

// hand back ownership
v
}
```

우리의 코드는 상당히 장황해 질 것입니다. 우리가 소유권을 가져오고 싶은 것들이 늘어날 수록 상황은 나빠지겠죠:

```rust
fn foo(v1: Vec, v2: Vec) -> (Vec, Vec, i32) {
// do stuff with v1 and v2

// hand back ownership, and the result of our function
(v1, v2, 42)
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let (v1, v2, answer) = foo(v1, v2);
```

아이구! 반환 타입, 반환 라인, 그리고 함수 호출 등이 모두 훨씬 복잡해 질 것입니다.

다행히도, 러스트는 이런 문제의 해결을 돕기 위해 빌림이라는 기능을 제공합니다. 다음 섹션의 주제죠!
readme
# 1. 소개(Introduction) - 10095%

환영합니다! 이 책은 당신에게 [Rust 프로그래밍 언어][rust]에 대해 알려줄 것입니다. Rust는 세가지 목표(안전성, 속도, 병행성)에 초점을 맞춘 시스템 프로그래밍 언어입니다. Rust는 가비지 콜렉터 없이 이러한 목표를 달성하고 있고, 때문에 다른 언어들이 그다지 훌륭하지 못한 몇 가지 부분에서 강세를 보입니다. 예를 들어 다른 언어에 내장(_embedding_)시키는 일, 특정한 공간/시간 제약을 갖는 프로그램을 작성하는 일, 장치 드라이버나 운영 체제 등의 로우 레벨 코드를 작성하는 일 등이죠. Rust는 컴파일 타임에 이루어지는 몇 가지 안정성 체크를 통해 런타임 오버헤드를 발생시키지 않으면서도 이러한 목표를 가진 현존하는 언어들보다 뛰어난 성과를 보여줍니다. 또한, Rust는 고수준 언어들이 제공하는 것과 비슷하게 느껴지는 추상화를 제공하면서도 '무비용 추상화_zero-cost abstraction_'을 달성하고자 합니다. 그러면서도, 많은 로우 레벨 언어들처럼 정밀한 제어도 가능케 하죠.

[rust]: https://www.rust-lang.org

“Rust 프로그래밍 언어”는 여덟 단원으로 구분됩니다. 이 소개는 그 중 첫번째고, 나머지는 다음과 같습니다.

* [시작하기(Getting started)][gs] - Rust 개발을 위한 컴퓨터 환경 구축.
* [Rust 배우기(Learn Rust)][lr] - 작은 프로젝트를 통한 Rust 프로그래밍의 학습.
* [효과적인 Rust(Effective Rust)][er] - 훌륭한 Rust 코드를 작성하기 위한 더 높은 수준의 개념들.
* [문법과 의미(Syntax and Semantics)][ss] - 조그만 조각들로 쪼개서 살펴보는 Rust의 세세한 부분들.
* [실험적 Rust(Nightly Rust)][nr] - 아직 안정적인 빌드에 포함되지 않은 최신 기능들.
* [용어 해설(Glossary)][gl] - 책에서 사용된 용어들의 참조.
* [학문적 연구(Academic Research)][ar] - Rust에 영향을 준 문헌.Bibliography][bi] - Background on Rust's influences, papers about Rust.

[gs]: getting-started.md
[lr]: learn-rust.md
[er]: effective-rust.md
[ss]: syntax-and-semantics.md
[nr]: nightly-rust.md
[gl]: glossary.md
[arbi]: academic-researchbibliography.md

이 글을 읽은 후, 'Rust 배우기'나 '문법과 의미' 둘 중 하나로 넘어가길 추천드립니다. 프로젝트를 하나 붙잡고 집중하고 싶다면 'Rust 배우기'를, 다음으로 넘어가기 전에 개념을 하나씩 완전히 익히는 것을 선호하신다면 '문법과 의미'를 선택하면 됩니다. 이 두 부분 사이엔 많은 다리들이 연결되어 있지요.

### 기여

이 책을 생성하는 원본 파일들은 Github에서 찾을 수 있습니다.
[github.com/rust-lang/rust/tree/master/src/doc/trpl](https://github.com/rust-lang/rust/tree/master/src/doc/trpl)

## Rust에 대한 간략한 소개

Rust는 당신이 흥미를 가질 만한 언어일까요? Rust의 장점 몇 가지를 보여주기 위해 짧은 예제 코드 몇 개를 살펴보죠.

Rust를 다른 어떤 언어와도 다른 것으로 만드는 주요 개념은 바로 '소유권'이라고 합니다. 다음 짧은 예제를 한 번 보죠.

```rust
fn main() {
let mut x = vec!["Hello", "world"];
}
```

이 프로그램은 `x`라는 이름의 [변수 바인딩][var]을 생성합니다. 이 바인딩의 값은 `Vec` 또는 '벡터'입니다. 우리는 이것을 표준 라이브러리에 정의되어 있는 [매크로][macro]를 통해서 만들었습니다. 이 매크로는 `vec`이라고 하는데, 모든 매크로는 `!`과 함께 실행됩니다. 이것은 Rust의 기본 원칙 중 하나를 따른 것입니다. "모든 것을 명시적으로 만들어라." 함수에 비교했을 때 매크로는 훨씬 더 복잡한 작업들을 할 수 있고, 따라서 둘은 외형적으로 구분됩니다. 또한 `!`은 파싱 과정을 도우며, 중요한 도구들을 작성하기 쉽도록 해 줍니다. 역시 중요한 점이죠.

우리는 `mut`를 사용해서 `x`를 변경 가능한 변수_mutable variable_로 만들었습니다. Rust에서는 변수 바인딩은 기본적으로 변경할 수 없습니다_immutable_. 우리는 나중에 이 벡터를 변경하는 예제도 살펴보죠.

타입을 명시적으로 기술하지 않았다는 것도 주목할만한 점이죠. Rust는 정적 타입 언어지만, 타입을 꼭 명시적으로 적을 필요가 없습니다. 정적 타이핑의 강력함과 타입을 장황하게 적어야 하는 불편함 사이에서 균형을 잡기 위해, Rust는 타입 추론(type inference) 기능을 가지고 있습니다.

Rust는 힙 할당보다 스택 할당을 선호합니다. `x`는 스택 위에 바로 할당됩니다. 그러나, `Vec` 타입은 벡터의 요소들을 저장하기 위한 공간을 힙에 할당합니다. 만약 무슨 차이인지 모르겠다면, 일단 여기에서는 무시해도 좋습니다. 아니면 [‘스택과 힙’][heap] 문서를 참고하셔도 좋구요. 시스템 프로그래밍 언어로서 Rust는 메모리를 어떻게 할당할 것인가에 대한 제어권을 사용자에게 제공합니다. 그러나 우리는 이제 막 시작하는 참이고, 이게 그렇게 중요한 일은 아니겠죠.

[var]: variable-bindings.md
[macro]: macros.md
[heap]: the-stack-and-the-heap.md

앞서 '소유권'이 Rust의 새로운 주요 개념이라고 언급한 바 있습니다. Rust 어법에서, `x`는 그 벡터를 '소유합니다'. 이는 `x`가 유효 범위(Scope)의 바깥으로 나갈 때, 그 벡터의 메모리가 해제된다는 것을 의미합니다. Rust 컴파일러는 이 과정을 쓰레기 수집(Garbage collection) 등의 방법을 통하지 않고 결정론적으로 수행합니다. 다른 말로 설명하면, Rust에서 여러분은 `malloc`이나 `free` 같은 함수를 직접 호출하지 않습니다. 컴파일러는 어느 시점에 메모리를 할당하고 해제해야 하는지를 정적으로 결정하고, 그런 호출을 스스로 집어넣습니다. 인간은 실수하는 동물이지만, 컴파일러는 절대 까먹지 않습니다.

우리 예제에 다른 한 줄을 추가해 봅시다.

```rust
fn main() {
let mut x = vec!["Hello", "world"];

let y = &x[0];
}
```

우리는 또 다른 바인딩 `y`를 도입했습니다. 여기에서 `y`는 벡터의 첫 번째 요소를 가리키는 '참조' 입니다. Rust의 참조는 다른 언어들의 포인터와 비슷하지만, 컴파일 시간에 수행되는 추가적인 안전성 검사를 가지고 있습니다. 참조들은 그들이 가리키는 것을 소유하는 대신 [‘빌림’][borrowing]으로써 소유권 시스템과 소통합니다. 참조는 유효 범위 바깥으로 나가더라도 자신이 가리키고 있던 메모리를 해제하지 않는다는 차이점을 가지고 있습니다. 만약 그렇지 않았다면 같은 메모리에 대한 두 번의 해제가 일어나겠죠. 그게 영 좋지 않은 일이란건 명백하구요!
[borrowing]: references-and-borrowing.md

세 번째 줄을 추가해 봅시다. 겉보기에는 별 문제 없어 보이는 코드입니다만, 이는 컴파일러 오류를 유발합니다.

```rust,ignore
fn main() {
let mut x = vec!["Hello", "world"];

let y = &x[0];

x.push("foo");
}
```
`push`는 벡터의 메서드로 또 다른 요소 하나를 벡터의 끝에 추가합니다. 이 프로그램을 컴파일하려 시도하면 다음과 같은 오류를 얻게 됩니다.

```text
error: cannot borrow `x` as mutable because it is also borrowed as immutable
x.push("foo");
^
note: previous borrow of `x` occurs here; the immutable borrow prevents
subsequent moves or mutable borrows of `x` until the borrow ends
let y = &x[0];
^
note: previous borrow ends here
fn main() {

}
^
```

휴! 때때로 Rust 컴파일러는 오류에 대해 상당히 자세히 알려줍니다. 그리고 이번이 바로 그런 때로군요. 오류 메시지에 따르면, 우리가 변수 바인딩을 변경할 수 있도록 만들음에도 불구하고 여전히 `push`를 호출할 수 없습니다. 이것은 우리가 벡터의 한 요소를 가리키는 참조 `y`를 이미 가지고 있기 때문입니다. 다른 참조가 가리키고 있는 무엇인가를 변경하는 것은, 우리가 그 참조를 무효화할 수도 있기 때문에 위험한 행동입니다. 이 경우를 구체적으로 살펴보면, 벡터를 생성할 때, 딱 두 개의 요소를 담을 수 있는 메모리만이 할당되었을 수도 있겠죠. 여기에 세 번째 요소를 추가한다는 것은 세 요소를 모두를 담을 수 있는 메모리 공간을 새롭게 할당하고, 기존 값들을 복사하고, 그 메모리를 가리키도록 내부 포인터를 업데이트하는 것을 의미합니다. 이러한 일련의 동작은 별 문제없이 작동합니다. 문제는 그 과정에서 `y`는 업데이트되지 않고, 따라서 '댕글링 포인터_dangling pointer_'를 갖게 된다는 것입니다. 좋지 않죠. 이 경우 `y`를 어떤 방식으로든 사용한다면 에러가 날 것이므로, 컴파일러가 우리를 위해서 잡아준 것입니다.

어떻게 이 문제를 해결할 수 있을까요? 두 가지 접근법을 취할 수 있습니다. 첫 번째 방법은 참조를 사용하는 대신 복제본을 만드는 것입니다.

```rust
fn main() {
let mut x = vec!["Hello", "world"];

let y = x[0].clone();

x.push("foo");
}
```

Rust는 기본적으로 [move semantics][move]을 따릅니다. 따라서 만약 어떤 데이터의 복제본을 만들고 싶다면, `clone()` 메소드를 호출합니다. 이 예제에서, `y`는 더 이상 `x`에 저장된 벡터를 가리키는 참조가 아니고, 그 첫 번째 요소의 복제본인 `"Hello"`입니다. 이제 참조가 존재하지 않으므로, `push()`는 잘 동작하겠죠.

[move]: ownership.htmlmd#move-semantics

만약 정말로 참조를 사용하고 싶다면, 또 다른 선택지가 필요합니다. 어떤 참조에 대한 변경이 시행되기 전에 반드시 그것이 유효 범위를 벗어나도록 만드는거죠. 다음과 같이 말입니다.


```rust
fn main() {
let mut x = vec!["Hello", "world"];

{
let y = &x[0];
}

x.push("foo");
}
```

우리는 추가적인 중괄호 쌍을 이용해 안쪽에 새로운 유효 범위를 만들었습니다. `y`는 우리가 `push()` 를 호출하기 전에 유효 범위를 벗어날 것이므로 문제는 발생하지 않겠죠.


이렇듯 소유권 시스템은 단지 댕글링 포인터뿐만 아니라, 반복자 무효화_iterator invalidation_, 동시성_concurrency_ 등 연관된 모든 문제점들을 예방하는데에 유용합니다.
references-and-borrowing
# 5.98. 참조와 빌림 (References and Borrowing) - 100%

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

* 핵심 개념인 [소유권][ownership]
* 여러분이 읽고 계시는 참조와 빌림
* [수명][lifetimes], 빌림의 고급 개념

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

[ownership]: ownership.html
[lifetimes]: lifetimes.html

# 개괄

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

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

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

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

# 빌림

[소유권][ownership] 섹션의 끝자락에서, 다음과 같은 복잡한 예제를 보았습니다:

```rust
fn foo(v1: Vec, v2: Vec) -> (Vec, Vec, i32) {
// do stuff with v1 and v2

// hand back ownership, and the result of our function
(v1, v2, 42)
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let (v1, v2, answer) = foo(v1, v2);
```

하지만, 사실 이 코드는 이상적인 러스트 코드는 아닙니다. 빌림 기능을 제대로 활용하지 못 하고 있기 때문이죠. 이상적인 코드로의 첫 단계는 다음과 같습니다:

```rust
fn foo(v1: &Vec, v2: &Vec) -> i32 {
// do stuff with v1 and v2

// return the answer
42
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let answer = foo(&v1, &v2);

// we can use v1 and v2 here!
```

위의 함수에서 우리는 `Vec` 타입을 인자로 받는 대신, 그에 대한 참조인 `&Vec`를 받습니다. 그리고 `v1`과 `v2`를 직접 넘기는 대신, `&v1`과 `&v2`를 넘기죠. `&T` 타입은 '참조'라고 불리는데, 이러한 타입은 리소스의 소유권을 갖지 않고 소유권을 빌려옵니다. 이렇듯 '빌려 오는' 바인딩은 그 바인딩의 스코프가 끝날 때 리소스의 할당을 해제하지 않습니다. 다시 말해, `foo()`의 호출이 끝난 후에도 기존의 바인딩을 다시 사용할 수 있는거죠.

바인딩과 마찬가지로, 참조는 불변_immutable_합니다. 즉, `foo()` 내에서 벡터들은 전혀 바뀔 수 없습니다:

```rust,ignore
fn foo(v: &Vec) {
v.push(5);
}

let v = vec![];

foo(&v);
```

는 다음과 같은 에러를 뱉죠:

```text
error: cannot borrow immutable borrowed content `*v` as mutable
v.push(5);
^
```

값을 푸쉬하는 것은 벡터를 변경하는 일이고, 따라서 허용되지 않습니다.

# &mut 참조

두번째 타입의 참조가 있습니다. `&mut T` 인데, 이러한 '가변_mutable_ 참조'는 당신이 빌린 리소스를 변경할 수 있게 합니다. 예를 들어:

```rust
let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", x);
```

위의 코드는 `6`을 출력합니다. 우리는 `x`에 대한 가변 참조로서 `y`를 만들었고, `y`가 가리키고 있는 것에 1을 더해줬죠. 이 때, `x` 역시 선언 당시 `mut`로 명시되었어야 합니다. 그렇지 않은 경우, 불변 값으로의 가변 빌림은 생성이 불가능합니다.

You'll also notice we added an asterisk (`*`) in front of `y`, making it `*y`,
this is because `y` is an `&mut` reference. You'll also need to use them for
accessing the contents of a reference as well.

그 점을 제외하면, `&mut` 참조는 기존의 참조와 비슷합니다. 다만, 실제로 그들이 어떻게 상호작용하는지에는 _지대한_ 차이가 존재하죠. 위의 예제에서, `{`와 `}`를 이용해 새로운 스코프를 만들어야 했다는 점에서 뭔가 수상한 점을 찾으셨을지도 모르겠네요. 만약 중괄호들을 제거하면 다음과 같은 에러가 발생합니다:

```text
error: cannot borrow `x` as immutable because it is also borrowed as mutable
println!("{}", x);
^
note: previous borrow of `x` occurs here; the mutable borrow prevents
subsequent moves, borrows, or modification of `x` until the borrow ends
let y = &mut x;
^
note: previous borrow ends here
fn main() {

}
^
```

알고 보니, 규칙들이 있는 모양이네요.

# 규칙들

다음은 러스트에서의 빌림에 관한 규칙들입니다:

첫째, 어떤 빌림이든 원래 주인보다 크지 않은 스코프에서만 생존할 수 있다. 둘째, 어떤 리소스에 대해 다음 두 종류의 빌림 중 어느 쪽이든 가질 수 있지만, 두 종류의 빌림을 동시에 유지할 수는 없다.

* 한 리소스로의 1개 또는 그 이상의 참조(`&T`)
* 한 리소스로의 정확히 1개의 가변 참조(`&mut T`)

어쩌면 이게 데이터 레이스의 정의와 굉장히 비슷한, 하지만 완벽히 같지는 않은 상황이라는 것을 알아차렸을지도 모르겠네요:

>만약 어떤 메모리 주소에 두 개 이상의 포인터가 동시에 접근하고, 그들 중 하나 이상의 포인터가 쓰기 작업을 하면서 명령들이 동기화되지 않는다면, '데이터 레이스'가 발생합니다.

만약 당신이 쓰기(변경) 작업을 하지 않는다면, 한 리소스에 대해 당신이 원하는 만큼의 참조가 가능합니다. 만약 쓰기 작업을 할거라면, 그 시점에서는 딱 하나의 `&mut` 참조만을 가질 수 있습니다. 이게 러스트가 컴파일 타임에 데이터 레이스를 방지하는 비결입니다: 만약 규칙을 어기면, 에러가 나게 되죠.

이 점을 명심한 채로, 예제를 다시 한 번 살펴봅시다.

## 스코프에 대해

다음 코드를 보시죠:

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

*y += 1;

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

이 코드는 다음과 같은 에러를 발생시킵니다:

```text
error: cannot borrow `x` as immutable because it is also borrowed as mutable
println!("{}", x);
^
```

규칙을 어겼기 때문에 일어나는 현상인데, `x`를 가리키는 `&mut T`를 가지고 있기 때문에 다른 `&T`를 생성할 수 없죠. 둘 중 하나만 골라야 하는 것, 기억 하시나요? 에러 메시지의 노트는 이 문제를 해결할 힌트를 줍니다:

```text
note: previous borrow ends here
fn main() {

}
^
```

다시 말해, 가변 참조가 우리의 예제의 나머지 내내 유지된다는거죠. 우리가 원하는 것은 `println!`의 호출 _이전에_ 가변 참조가 긑이 나고, 다른 불변 참조의 생성이 가능해지는 것이죠. 러스트에서, 빌림은 그 빌림이 유효한 스코프와 짝지어집니다. 그리고 현재 스코프는 다음과 같죠:

```rust,ignore
let mut x = 5;

let y = &mut x; // -+ &mut borrow of x starts here
// |
*y += 1; // |
// |
println!("{}", x); // -+ - try to borrow x here
// -+ &mut borrow of x ends here
```

스코프 간의 충돌이 일어납니다: `y`가 스코프 내에 있는 동안 `&x`를 만들 수는 없어요.

그래서 다음과 같이 꺾인 괄호를 추가하면:

```rust
let mut x = 5;

{
let y = &mut x; // -+ &mut borrow starts here
*y += 1; // |
} // -+ ... and ends here

println!("{}", x); // <- try to borrow x here
```

문제는 사라집니다. 가변 빌림은 불변 빌림이 일어나기 전에 스코프에서 사라지죠. 스코프는 빌림이 얼마나 오래 유지될지를 확인하는 핵심 요소입니다.

## 빌림으로 인해 예방되는 문제들

왜 이런 제한적인 규칙들을 따라야 하냐고요? 음, 우리가 이미 이야기했듯이 이러한 규칙들은 데이터 레이스를 예방합니다. 데이터 레이스가 일어나면 어떤 문제들이 일어날까요? 몇 가지 살펴봅시다.

### 반복자 무효화 _Iterator invalidation_

한 예는 '반복자 무효화'입니다. 당신이 반복중인 콜렉션을 변경하려 할 때 일어나죠. 러스트의 소유권 검사기는 이러한 일을 방지합니다:

```rust
let mut v = vec![1, 2, 3];

for i in &v {
println!("{}", i);
}
```

위의 코드는 1에서 3까지를 출력합니다. 벡터를 따라 반복하면서, 우리는 각 원소에 대한 참조만을 갖게 됩니다. `v` 자체가 불변 형식으로 빌려졌기 때문에, 반복자를 도는 동안 그것을 변경할 수 없음을 알 수 있죠:

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

for i in &v {
println!("{}", i);
v.push(34);
}
```

위의 코드는 다음과 같은 에러를 발생시킵니다:

```text
error: cannot borrow `v` as mutable because it is also borrowed as immutable
v.push(34);
^
note: previous borrow of `v` occurs here; the immutable borrow prevents
subsequent moves or mutable borrows of `v` until the borrow ends
for i in &v {
^
note: previous borrow ends here
for i in &v {
println!(“{}”, i);
v.push(34);
}
^
```

반복문에 의해 `v`가 빌려졌기 때문에, 반복문 내에서 `v`를 변경할 수 없는거죠.

### 해제 이후의 사용 _use after free_

참조는 그것이 가리키고 있는 리소스보다 오래 살아남을 수 없습니다. 러스트는 당신의 참조들의 스코프를 체크해서 이게 늘 참으로 유지될것을 보장합니다.

만약 러스트가 이것을 체크하지 않는다면, 우리는 더이상 유효하지 않은 참조를 사용할지도 모릅니다. 예를 들어 보죠:

```rust,ignore
let y: &i32;
{
let x = 5;
y = &x;
}

println!("{}", y);
```

위의 코드는 다음과 같은 에러를 발생시킵니다:

```text
error: `x` does not live long enough
y = &x;
^
note: reference must be valid for the block suffix following statement 0 at
2:16...
let y: &i32;
{
let x = 5;
y = &x;
}

note: ...but borrowed value is only valid for the block suffix following
statement 0 at 4:18
let x = 5;
y = &x;
}
```

다시 말해, `y`는 `x`가 존재하는 스코프 내에서만 유효하다는 것이죠. `x`가 사라져버린 후에도 `x`를 참조한다는 것은 이치에 맞지 않습니다. 참조의 실제 수명과 그것이 살아남아야 할 시간간의 불일치로 인해 에러가 발생하고, 따라서 `x`가 '충분히 오래 살아있지 않는다'는 에러가 발생하는 것이죠.

참조가 자신이 가리키는 변수의 선언 _이전에_ 선언 될 때도 같은 문제가 발생합니다. This is because resources within the same scope are freed in the opposite order they were declared:

```rust,ignore
let y: &i32;
let x = 5;
y = &x;

println!("{}", y);
```

다음과 같은 에러가 발생합니다:

```text
error: `x` does not live long enough
y = &x;
^
note: reference must be valid for the block suffix following statement 0 at
2:16...
let y: &i32;
let x = 5;
y = &x;

println!("{}", y);
}

note: ...but borrowed value is only valid for the block suffix following
statement 1 at 3:14
let x = 5;
y = &x;

println!("{}", y);
}
```

In the above example, `y` is declared before `x`, meaning that `y` lives longer than `x`, which is not allowed.
release-channels
# 4.101. 배포 채널 (Release Channels) - 1080%

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.
rust-inside-other-languages
# 3.3. 다른 언어에 Rust 포함하기 (Rust Inside Other Languages) - 100%

여기서는, 러스트의 가장 끝내주는 특징 중 하나를 자랑하겠습니다: 런타임 경량화

프로그램 구조가 비대해질수록, 더욱 더 많은 프로그래밍 언어에 의존하게 됩니다. 각 언어들은 서로 다른 장점과 단점을 지니며, 그에 따라 적재적소에 다양한 언어들을 사용하는 폴리글랏(Polyglot)이 주목받게 되었습니다.

많은 언어들의 공통적인 약점은 역시 프로그램의 런타임 성능(Performance)입니다. 대체로 프로그램의 성능을 낮추는 언어들은, 그 약점을 감수할 만큼의 생산성을 제공하기 때문에 개발자들은 이를 기꺼이 받아들이게 됩니다 . 성능에서의 손실을 줄이기 위해, 시스템의 일부분을 C언어로 작성하고 현재 사용하고 있는 상위 언어에서 C로 작성된 코드를 부를 수 있도록 하는 방법이 있습니다. 이를 '외부 함수 인터페이스', 줄여서 'FFI(foreign function interface)'라고 합니다.

러스트는 FFI를 양방향으로 지원합니다. 즉 러스트 코드 안에서 C 코드를 매우 쉽게 호출할 수 있을 뿐 아니라, 결정적으로, 러스트 또한 C처럼 간단하게 _호출될_ 수 있습니다. 다른 언어 안에서 더 강렬한 무언가를 원할 때, 쓰레기 수집기(GC)가 없고 뛰어난 성능을 가진 러스트와의 결합은 좋은 선택지가 될 수 있습니다.

상세한 정보는 [chapter devoted to FFI][ffi] 에 있지만, 이 챕터에선 루비, 파이썬, 자바스크립트와의 간단한 FFI 사용 예시를 보이겠습니다.

[ffi]: ffi.html

# The problem

많은 다른 예제들을 선택할 수 있지만, 여기서는 다른 언어에 비해 러스트의 이점을 확연히 드러내줄 수 있는 예제들을 택했습니다: 계산 성능과 스레딩.

많은 언어에서는 일관성을 위해, 계산할 메모리들을 스택(stack)보다는 힙(heap)에 위치시킵니다. 특히 객체지향 프로그래밍이나 쓰레기 수집기(GC)를 사용하는 언어들은 힙 할당이 기본적입니다. 때때로 최적화기(optimizer)에 의존하는 것보다 우리가 여러 객체 타입들보다 원시 숫자 타입(primitive number types)들만을 사용한다고 보장하여, 특정 계산들을 스택에 할당하는 것으로 최적화를 달성할 수도 있습니다.

두번째로, 많은 언어들은 많은 상황에서 동시성을 제한하는 '전역 인터프리터 잠금'(GIL, Global Interpreter Lock)을 가집니다. 안전성을 달성한다는 목적에서는 좋은 방향으로 작용하지만, 한번에 처리할 수 있는 일을 제한한다는 점에서 나쁜 작용이 됩니다.

이 두 가지 측면을 드러내기 위해, 작은 프로젝트 하나를 실행해봅니다. 프로젝트 자체보다는 다른 언어 안에서 러스트를 결합하는 것에 집중할 것이기 때문에, 단순한 프로젝트를 사용합시다:

> 스레드 10개로 시작하여, 각 스레드 안에 500만을 카운트합니다. 모든 스레드의 일이 끝나면,
> 'done!'을 출력합니다.

루비로 된 예제는 다음과 같습니다:

```ruby
threads = []

10.times do
threads << Thread.new do
count = 0

5_000_000.times do
count += 1
end

count
end
end

threads.each do |t|
puts "Thread finished with count=#{t.value}"
end
puts "done!"
```

예제를 실행하여, 얼마나 걸리는지 세 봅시다.
각 컴퓨터 하드웨어가 다르기 때문에, 소요 시간이 예제의 경우와 다를 수 있습니다.

제 시스템에서는, 프로그램을 실행시키는데 `2.156`초가 걸렸습니다. 그리고 프로세스 모니터링 도구 중 하나인 `top`을 사용해보면, 제 컴퓨터 중 코어를 하나만 사용하고 있는 것을 확인할 수 있습니다. 이것이 GIL의 정체입니다.

단지 프로그램일 뿐이지만, 눈치 좋은 누군가는 이 문제가 현실 세계에도 일어나는 것을 쉽게 상상해볼 수 있습니다. 그 문제는 바로, 계산들을 도맡아 바쁘게 일하는 스레드가 몇 안된다는 것입니다. 병렬적인 업무에서 계산이 느려지는 이유입니다.

# A Rust library

이 문제를 러스트로 해결해보죠. Cargo에서 새로운 프로젝트를 만듭시다:

```bash
$ cargo new embed
$ cd embed
```

러스트로 간단히 다음과 같이 쓸 수 있습니다:

```rust
use std::thread;

fn process() {
let handles: Vec<_> = (0..10).map(|_| {
thread::spawn(|| {
let mut x = 0;
for _ in (0..5_000_000) {
x += 1
}
x
})
}).collect();

for h in handles {
println!("Thread finished with count={}",
h.join().map_err(|_| "Could not join a thread!").unwrap());
}
println!("done!");
}
```

지난 예시에서 볼 수 있었던 익숙한 모습이 보이네요. 스레드 10개를 생성하여, `handles` 벡터 안에 넣습니다. 각 스레드 내부에서 한 번 돌때마다 `x` 값을 올리는 루프를 500만번 실행합니다. 그리고 각 스레드를 연결합니다.

하지만 지금은 러스트 라이브러리를 사용했기 때문에, C로부터 호출하는 게 아닙니다. 따라서 이것을 곧바로 다른 언어에서 결합할 수는 없습니다. 그러기 위해서는 2가지의 명시가 필요합니다. 첫번째로, 수정할 코드의 시작은:

```rust,ignore
#[no_mangle]
pub extern fn process() {
```

우리는 새로운 속성인 `no_mangle`을 명시해주어야만 합니다. 러스트 라이브러리를 만들 때, 이것은 컴파일된 결과물에서 함수의 이름을 바꿉니다. 이 튜토리얼에서 이 구문이 스코프 밖에 있는 이유는 다른 언어에서 이 함수를 부르는 방법을 알려주기 위해서입니다. 이 속성은 어떤 명령의 실행과는 관계가 없습니다.

다른 변화된 점은 `pub extern`입니다. `pub`은 이 함수가 모듈 바깥에서 호출될 수 있어야 함을 뜻하고, `extern`은 C로부터 호출될 수 있어야 함을 말해줍니다. 이게 다입니다! 그렇게 바뀌진 않았죠.

두번째로 우리는 `Cargo.toml`의 설정을 변경해주어야 합니다. 맨 밑에 다음을 추가하세요:

```toml
[lib]
name = "embed"
crate-type = ["dylib"]
```

이것은 우리의 라이브러리를 러스트의 표준 동적 라이브러리(standard dynamic library)에 컴파일하길 원한다고 말해줍니다. 기본적으로 러스트는 'rlib'라는 러스트 상세 포맷을 컴파일합니다.

빌드해보죠:

```bash
$ cargo build --release
Compiling embed v0.1.0 (file:///home/steve/src/embed)
```

최적화와 함께 빌드하라는 `cargo build --release` 명령을 사용했습니다. 가능한 이것을 빠르게 하고 싶거든요! `target/release` 안에 라이브러리의 결과물을 볼 수 있습니다.

```bash
$ ls target/release/
build deps examples libembed.so native
```

`libembed.so`는 우리의 '공유 객체' 라이브러리입니다. 이제 이것을 C로 쓰여진 공유 객체 라이브러리처럼 마음껏 사용할 수 있습니다! 플랫폼에 따라, `embed.dll` 또는 `libembed.dylib`가 되기도 합니다.
빌드된 러스트 라이브러리를 손에 넣었으니, 루비에서 직접 사용해봅시다.

# Ruby

`embed.rb`를 열어 다음과 같이 합니다.

```ruby
require 'ffi'

module Hello
extend FFI::Library
ffi_lib 'target/release/libembed.so'
attach_function :process, [], :void
end

Hello.process

puts 'done!'
```

실행하기 전에, 우리는 `ffi` gem을 설치해야 합니다:

```bash
$ gem install ffi # this may need sudo
Fetching: ffi-1.9.8.gem (100%)
Building native extensions. This could take a while...
Successfully installed ffi-1.9.8
Parsing documentation for ffi-1.9.8
Installing ri documentation for ffi-1.9.8
Done installing documentation for ffi after 0 seconds
1 gem installed
```

마침내, 실행해 볼 수 있게 됐습니다:

```bash
$ ruby embed.rb
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
Thread finished with count=5000000
done!
done!
$
```

와, 정말 빠릅니다! 제 시스템에서는 `0.086`초가 걸렸습니다. 순수한 루비 프로그램이 2초 정도 걸렸는데 말입니다. 이제 코드를 파헤쳐볼까요?

```ruby
require 'ffi'
```

첫번째로 `ffi` gem을 불러옵니다. require를 통해 마치 C 라이브러리처럼 러스트 라이브러리에 접근할 수 있습니다.

```ruby
module Hello
extend FFI::Library
ffi_lib 'target/release/libembed.so'
```

`Hello` 모듈은 공유 라이브러리의 네이티브 함수를 루비에 붙이는 데에 사용합니다. 다음으로 `FFI::Library`를 `extend`할 필요가 있으며, `ffi_lib`를 호출해 공유 객체 라이브러리를 가져옵니다. 우리는 그저 라이브러리가 있는 경로를 넘겨주었습니다. 보는 바와 같이 `target/release/libembed.so` 입니다.

```ruby
attach_function :process, [], :void
```

`attach_function`는 FFI gem에 의해 제공된 메소드입니다. 러스트 안의 `process()` 함수를 같은 이름의 루비 함수와 연결합니다. `process()` 함수는 받는 인자가 없기 때문에 `attach_function`의 두번째 인자는 빈 배열이며, 반환값도 없기 때문에 마지막 인자에 `:void`를 넘깁니다.

```ruby
Hello.process
```

이것이 실제로 러스트 함수를 호출하는 방법입니다. 우리의 `module`과 결합한 다음 `attach_function`에서 연결한 함수를 부릅니다. 마치 루비 함수 같아보이지만 실제로는 러스트입니다!

```ruby
puts 'done!'
```

마지막으로, 우리의 프로젝트가 그랬던 것처럼, `done!`을 출력합니다.
이게 전부입니다! 보았던 대로 두 언어간의 결합이 매우 간단하며, 엄청난 성능을 얻을 수 있습니다.
다음은 파이썬으로 해보죠!

# Python

`embed.py`파일을 만들고 다음의 코드를 입력합니다:

```python
from ctypes import cdll

lib = cdll.LoadLibrary("target/release/libembed.so")

lib.process()

print("done!")
```

아주 쉽죠! `ctypes`모듈로부터 `cdll`을 사용할 수 있습니다. `LoadLibrary`를 호출한 뒤, `process()`를 호출할 수 있습니다.

제가 테스트한 환경에서, `0.017`초가 걸렸군요. 빨라요!

# Node.js

Node는 언어가 아니지만, 현재 가장 주류로 떠오르고 있는 서버사이드 자바스크립트입니다.

Node에서 FFI를 이용하기 위해, 우리는 다음 라이브러리를 설치합니다.

```bash
$ npm install ffi
```

설치 후에는, 다음과 같이 이용합니다:

```javascript
var ffi = require('ffi');

var lib = ffi.Library('target/release/libembed', {
'process': ['void', []]
});

lib.process();

console.log("done!");
```

파이썬보다는 마치 루비 예제 같네요. 우리는 `ffi` 모듈을 객체로 받아온 뒤, 그 객체를 통해 `ffi.Library()`에 접근합니다. 리턴 타입과 인자 타입을 명시할 필요가 있는데, 이 예제에서는 리턴 타입으로 `'void'` , 인자가 없다는 것을 뜻하는 `[]`를 명시해주었습니다. 이제 이것을 호출하고 결과를 봅시다.

저의 테스트 환경에서는 `0.092`초가 걸렸네요. 준수한 성능입니다.

# 결론

보시다시피, 다른 언어에 rust를 포함하는 것은 기본적으로 _매우_ 쉽습니다.
물론 여기서부터 해볼만한 더 많은 것들이 있지만요. 더 자세히 알아보고 싶다면
[FFI][ffi]챕터를 참고해주세요.
structs
# 5.121. 구조체 (Structs) - 100%

구조체는 좀 더 복잡한 데이터 타입을 만드는데 사용합니다. 예를 들어, 2D 좌표를 다루고 싶을 때 우리는 `x`와 `y`를 다음과 같이 쓰겠죠:

```rust
let origin_x = 0;
let origin_y = 0;
```

구조체는 이 두가지를 마치 하나의 데이터타입처럼 엮을 수 있게 해줍니다:

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

fn main() {
let origin = Point { x: 0, y: 0 }; // origin: Point

println!("The origin is at ({}, {})", origin.x, origin.y);
}
```

많은 것들이 보이는데, 한번 헤쳐나가보죠. `struct` 키워드를 통해 Point라는 이름의 구조체를 정의합니다. 관습적으로 `struct`의 이름은 캐멀 케이스로 쓰여집니다: `Point_In_Space`가 아닌, `PointInSpace`등으로 작성합니다.

`let` 키워드를 통해 구조체의 인스턴스를 하나 만들고 `key: value` 스타일로 각 필드(구조체의 값들)를 설정합니다. 이 순서는 반드시 원래 구조체의 필드들을 따를 필요는 없습니다.

마지막으로, 점 표기법을 이용해 각 필드에 접근할 수 있습니다: `origin.x`

구조체의 값들은 기본적으로 불변이며, 러스트의 다른 바인딩들처럼 `mut` 키워드를 통해 가변으로 만들 수 있습니다:

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

fn main() {
let mut point = Point { x: 0, y: 0 };

point.x = 5;

println!("The point is at ({}, {})", point.x, point.y);
}
```

`The point is at (5, 0)`을 출력합니다.

러스트는 각 필드의 가변성을 언어 차원에서 지원하지 않으므로, 다음과 같이는 쓸 수 없습니다:

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

가변성은 바인딩의 성질에 따라서 이루어질 뿐이지, 구조 자체에 있는 것이 아닙니다. 만약 필드 차원에서 변경 가능하게 하고 싶다면, 처음엔 좀 이상할진 모르지만, 무척이나 간단한 일입니다. 다음과 같이 쓰면 필드 차원의 가변성을 달성할 수 있습니다:


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

fn main() {
let mut point = Point { x: 0, y: 0 };

point.x = 5;

let point = point; // 이 새로운 바인딩은 이제부터 변경 불가능입니다.

point.y = 6; // 에러를 일으킵니다.
}
```

# Update syntax

`struct` 키워드는 내부의 값들을 다른 구조체에 복사할 수 있도록 `..`를 제공합니다:

```rust
struct Point3d {
x: i32,
y: i32,
z: i32,
}

let mut point = Point3d { x: 0, y: 0, z: 0 };
point = Point3d { y: 1, .. point };
```

`point`에서 `y`는 새로운 값으로 설정했지만, `x`와 `z`는 기존 값을 유지합니다. `struct`와 같은 필요는 없으며, 이 구문은 새로운 바인딩을 만들 때, 값들을 일일히 다시 써주지 않고 복사할 수 있습니다.

```rust
# struct Point3d {
# x: i32,
# y: i32,
# z: i32,
# }
let origin = Point3d { x: 0, y: 0, z: 0 };
let point = Point3d { z: 1, x: 2, .. origin };
```

# Tuple structs

러스트는 [tuple][tuple]과 구조체 사이에 '튜플 구조체(tuple struct)'라 불리는 변종 데이터 타입을 가지고 있습니다. 구조체 자체는 이름을 가지지만, 그 필드들은 이름이 없는 것이 튜플 구조체입니다.

```rust
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
```

[tuple]: primitive-types.html#tuples

이 둘은 같은 값을 가지지만, 표현하는 것은 결코 같지 않습니다. 조금은 헷갈립니다.

```rust
# struct Color(i32, i32, i32);
# struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
```

이렇게 본다면 튜플 구조체를 쓰는 것보다 구조체를 쓰는 것이 더 낫습니다. `Color`와 `Point`를 다음과 같이 써봅시다:

```rust
struct Color {
red: i32,
blue: i32,
green: i32,
}

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

이제, 필드들이 실질적인 이름을 갖게 되었고 보다 명확해졌습니다. 좋은 명세의 중요성을 깨닫게 되었습니다.

튜플 구조체가 더 유용할 때가 _있는데_ 바로 오직 하나의 원소로 이루어진 경우입니다. 이것을 '뉴타입(newtype)' 패턴이라 부릅니다. 그것이 담고 있는 값 그리고 표현하고 있는 의미와 구별되는 새로운 타입을 만들수 있기 때문입니다.

```rust
struct Inches(i32);

let length = Inches(10);

let Inches(integer_length) = length;
println!("length is {} inches", integer_length);
```

보다시피, 보통 튜플처럼 디스트럭처링 할당을 이용해 내부 정수 타입을 추출할 수 있습니다. 이 경우에 `let Inches(integer_length)`의 `integer_length`에는 `10`이 할당됩니다.

# Unit-like structs

구조체를 멤버 없이 정의할 수도 있습니다:

```rust
struct Electron;
```

이 구조체는 '단위 유사(unit-like)' 라고 합니다. 그 이유는 '단위(unit)'이라 불리는 비어있는 튜플인 `()`와 닮았기 때문입니다. 튜플 구조체와 같이 뉴타입을 정의합니다.

이것은 그 자체로는 많이 쓰이지는 않지만, 다른 것들과 함께 쓰면 유용해질 수 있습니다. 예를 들어, 라이브러리를 만들 때 당신은 특정 [trait][trait]들을 상속해 구현될 구조체를 만들 경우가 있습니다. 그때 딱히 부가적으로 다른 어떤 데이터도 필요 없을 때, 그저 단위 유사 구조체를 만들고 그 안에 트레잇들을 구현하면 됩니다.

[trait]: traits.html
testing
# 4.2. 테스팅 (Testing) - 10095%

> 프로그램 테스팅은 버그의 존재를 보이는 매우 효과적인 방법일 수 있지만,
> 버그가 없다는 걸 보이는 데는 절망적으로 부적합하다.
>
> 에츠허르 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 '
' 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이 아닌 상태 코드를 반환하는데...

```bash
$ echo $?
101
We can use `$?` on OS X and Linux:

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

On Windows, if you’re using `cmd`:

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

And if you’re using 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!`를 쓰는 흔한 방법입니다.

# The `ignore` attribute

Sometimes a few specific tests can be very time-consuming to execute. These
can be disabled by default by using the `ignore` attribute:

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

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

Now we run our tests and see that `it_works` is run, but `expensive_test` is
not:

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

The expensive tests can be run explicitly using `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
```

The `--ignored` argument is an argument to the test binary, and not to cargo,
which is why the command is `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). 여기에 구체화돤 `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`와 같이 당신이 예제를 붙여나감에 따라 자동적으로 증가할 것입니다.
the-stack-and-the-heap
# 4.1. 스택과 힙 (The Stack and the Heap) - 100%

시스템 언어로서, Rust는 낮은 레벨에서 동작합니다. 여러분이 높은 레벨의 언어에서 왔다면, 시스템 프로그래밍의 어떤 면들은 익숙하지 않을 수 있습니다. 중요한 것은 스택과 힙과 함께 메모리가 어떻게 동작하는지 이해하는 것입니다. 여러분이 C 계열의 언어 스택 할당을 이용하는 방법에 익숙하다면, 이 단원은 복습이 될 것입니다. 그렇지 않다면, 이에 대한 더 일반적인 개념을 배울 것이지만 Rust에 초점이 맞춰질 것입니다.

## 메모리 관리 (Memory management)

이 두가지 용어는 모두 메모리 관리에 관한 것입니다. 스택과 힙은 우리가 메모리 할당, 해제를 알 수 있도록(이해할 수 있도록) 도와주는 추상화 개념입니다.

두 용어의 비교:

스택은 매우 빠르고 Rust 에서 기본적으로 메모리가 할당되는 곳입니다. 하지만 할당 장소(접근 범위)가 함수 호출 범위 내로 한정되고, 크기 또한 한정되어 있습니다. 힙은 느리고, 우리가 작성한 프로그램(코드)에 의해 명시적으로 할당됩니다. 하지만 힙은 사이즈가 제한이 없고, 전역적(globally)으로 접근할 수 있습니다.

# 스택 (The Stack)

한번 이 Rust 프로그램에 대하여 대화하여 봅시다.

```rust
fn main() {
let x = 42;
}
```

이 프로그램은 `x`라는 단 하나의 변수 바인딩을 가지고있습니다. 이것은 할당되기 위해 어딘가에 메모리 공간이 필요합니다. Rust 는 Stack 할당을 기본으로 한다고 하였습니다. 즉 기본적인 값은 스택으로 이동됩니다. 이것이 무엇을 의미할까요?

음, 함수가 호출되는 경우, 메모리는 이것의 로컬(지역) 변수들과 다른 정보들을 위해 할당됩니다. 이것을 '스택 틀(Stack Frame)' 이라고 부릅니다. 그리고 이 강좌의 목적입니다. 우리는 나머지(extra) 정보들을 무시하고 그저 우리가 할당한 지역 변수만 고려하도록 하겠습니다. 이 케이스에서 `main()` 이 실행될 때 (호출될 때), 우리는 '스택 프레임'에 32비트 정수 하나를 할당합니다. 이것들은 자동으로 우릴 위해 처리됩니다. 위 코드에서 볼 수 있듯이, 우리는 스택에 할당을 하기위해 특별한 Rust 코드 또는 다른 어느 특별한 것도 해주지 않아도 됩니다.

함수 호출이 끝날때, '스택 프레임'은 할당 해제가 됩니다. 이 작업 또한 자동으로 이루어집니다. 즉 스택의 할당 해제 또한 특별히 아무것도 해주지 않아도 됩니다.

그것이 이 간단한 프로그램의 전부입니다. 여기서 중요한 것은 스택 할당이 매우, 매우 빠르단 것 입니다. 우리는 모든 지역변수를 사전에 알고있기 때문에, 메모리를 할당할 때 한번에 할당하는 것이 가능합니다. 그리고 이후에 우리는 동시에 할당과 마찬가지로 제거 또한 매우 빠르게 할 수 있습니다.
단점으론 호출된 함수가 끝나게 되면 값을 유지할 수 없다는 것 입니다. 우리는 또한 ‘Stack’ 이란 이름용어에 대하여 설명하지 않았습니다. 이를 위해, 우리는 좀더 복잡한 예제를 살펴볼 필요가 있습니다:

```rust
fn foo() {
let y = 5;
let z = 100;
}

fn main() {
let x = 42;

foo();
}
```

이 프로그램은 총 3개의 변수를 가지고 있습니다: 두 개는 `foo()` 안에 있고, 나머지 하나는 `main()` 안에 있습니다. 이전과 마찬가지로, `main()`이 호출되면, 한 개의 정수가 스택 메모리에 할당됩니다. 하지만 `foo()`가 실행되었을 때를 살펴보기 전에, 메모리에서 무엇이 일어나고 있는지 그림으로 설명해보겠습니다.

OS가 프로그램에 제공하는 메모리의 모습은 단순합니다: 0부터 시작해서 큰 숫자까지 이어지는 거대한 주소들의 리스트입니다. 이 리스트는 컴퓨터가 가지고 있는 RAM이 얼마나 되는지를 나타냅니다. 예를 들어, 1기가 바이트의 RAM을 가지고 있다면, 이 주소들의 목록은 `0`부터 `1,073,741,8243`까지가 됩니다. 이 숫자는 230을 의미합니다.

이 메모리는 거대한 배열과 비슷합니다: 주소들은 0부터 시작해서, 마지막 숫자까지 올라갑니다.
우리의 첫 번째 스택 프레임을 다이어그램으로 만들어보았습니다.

| 주소 | 이름 | 값 |
|---------|------|-------|
| 0 | x | 42 |

우리는 `42`의 값을가지고 `0` 번째 주소에 위치한 `x`를 얻었습니다.

`foo()`가 호출될때, 새로운 스택 프레임이 할당 되었습니다:

| Address | Name | Value |
|---------|------|-------|
| 2 | z | 100 |
| 1 | y | 5 |
| 0 | x | 42 |

1번째 그리고 2번째 주소를 foo() 함수가 사용하였습니다, 왜냐하면 0번째 주소는 첫번째 프레임(`main()`)이 이미 사용하고 있기 때문입니다. 그것은 우리가 함수들을 호출하면 할수록 점점 자라나게 됩니다.

여기서 우리가 노트에 적어야 할 중요한 사실들이 있습니다. 위에서 주소로 사용한 0, 1 그리고 2는 예시설명을 목적으로 하기 때문에 실제 컴퓨터가 사용하는 단위와는 상관이 없습니다. 특히, 주소 세트는 실제로 몇 바이트단위로 분리하고, 이 분리된 크기가 저장된 값의 크기보다 클 수도 있습니다.

`foo()`가 종료되면, 프레임의 할당이 해제됩니다:

| Address | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

그리고 `main()` 까지 종료되면 마지막남은 값(변수 `x`) 까지 사라지게 됩니다. 쉽지요!

이것을 ‘Stack’ 이라고 합니다 왜냐하면 이것은 마치 음식을 담는 접시처럼 쌓이는 것과 같이 동작하기 때문입니다.(당신이 내려놓은 첫번째 접시는 다시 접시를 가져갈 때 제일 마지막에 가져갈 수 있습니다.)
스택은 때때로 Last in, First Out(LIFO) Queues라고 불리는데 그 이유는 마지막에 들어간 값이 제일 처음으로 나오기 때문입니다.

자 이제 좀더 어려운 예제를 시도해보도록 합시다:

```rust
fn bar() {
let i = 6;
}

fn foo() {
let a = 5;
let b = 100;
let c = 1;

bar();
}

fn main() {
let x = 42;

foo();
}
```

이번에도 우리는 첫번째로 `main()` 함수를 호출합니다:

| Address | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

다음으론, `main()` 에서` foo()`를 호출합니다:

| Address | Name | Value |
|---------|------|-------|
| 3 | c | 1 |
| 2 | b | 100 |
| 1 | a | 5 |
| 0 | x | 42 |

그 다음엔, `foo()` 에서 `bar()` 를 호출합니다:

| Address | Name | Value |
|---------|------|-------|
| 4 | i | 6 |
| 3 | c | 1 |
| 2 | b | 100 |
| 1 | a | 5 |
| 0 | x | 42 |

휴~ 우리의 스택이 무럭무럭 자라나고 있습니다!

`bar()` 이 종료된후, `foo()` 와 `main()` 을 남겨두고 `foo()` 의 프레임만 할당 해제가 됩니다:

| Address | Name | Value |
|---------|------|-------|
| 3 | c | 1 |
| 2 | b | 100 |
| 1 | a | 5 |
| 0 | x | 42 |

그리고 `foo()` 가 종료 되면, 오직 `main()` 만이 남게 됩니다.

| Address | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

자 이제 끝났습니다. 이것의 요령이 보이시는가요? 이건 마치 제일위에 접시를 추가하고, 다시 제일 위의 접시를 가져오는 것과 같습니다.

# 힙(The Heap)

자 이제, 이것은 정말 잘 작동합니다, 하지만 모든 것이 이것처럼 작동하는 것은 아닙니다. 때때로, 우리는 다른 함수간에 메모리를 주고받아야 하거나 함수의 실행후에도 값을 유지하고 싶을때도 있습니다. 우리는 힙을 사용하여서 이것을 해결할수 있습니다.

러스트에선, 당신은 [`Box` type][box] 을 통해 힙에 메모리를 할당할수 있습니다.
아래는 예시입니다:

```rust
fn main() {
let x = Box::new(5);
let y = 42;
}
```

[box]: ../std/boxed/index.html

아래의 다이어그램은 `main()` 이 호출된후에 메모리에서 일어난 일을 나타냅니다.

| Address | Name | Value |
|---------|------|--------|
| 1 | y | 42 |
| 0 | x | ?????? |

우리는 스택에 2개의 변수를 할당했습니다. `y`는 명시된 값 `42`로. 그런데, `x`는 어떨까요? 음, `x`는 `Box` 타입이고, box는 힙에 할당된다고 했습니다. 사실, box의 값은 힙에 대한 포인터를 가지는 구조로 되어있습니다. 함수를 실행하기 시작했을 때, `Box::new()`가 실행되어 힙 주소 어딘가에 메모리를 할당하고 `5`를 넣습니다. 메모리는 다음과 같습니다:

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 5 |
| ... | ... | ... |
| 1 | y | 42 |
| 0 | x | 230 |

230는 1GB의 RAM을 가지는 컴퓨터라고 가정했기 때문입니다. 스택이 0부터 시작하기 때문에, 메모리를 가장 간단히 할당하는 방법은 반대편 끝에서부터 시작하는 것입니다. 그래서 우리의 첫번째 값이 메모리의 가장 높은 곳에 위치하고 있습니다.

요약하자면 [raw pointer][rawpointer]를 가지는 `x` 구조체의 값은 우리가 힙에 할당한 230가 되고, 이 값을 메모리 주소로 요청하여 실제 값을 받습니다.

[rawpointer]: raw-pointers.html

우리는 아직 진정한 의미에서의 할당(allocate)과 해제(deallocate)를 논하지 않았습니다. 이 주제를 심도있게 논하는 것은 튜토리얼의 범위를 벗어나지만, 여기에서 가장 강조하는 것은 힙은 단지 스택의 반대편에서부터 할당되는 것이 아니라는 겁니다.

차후 예제에서 다루겠지만 힙은 순서에 상관없이 해제될 수 있기 때문에 '구멍'이 생길 수 있게 됩니다. 우리가 실행하는 프로그램의 메모리 다이어그램을 살펴보면 이렇습니다:

| Address | Name | Value |
|----------------------|------|----------------------|
| 230 | | 5 |
| (230) - 1 | | |
| (230) - 2 | | |
| (230) - 3 | | 42 |
| ... | ... | ... |
| 3 | y | (230) - 3 |
| 2 | y | 42 |
| 1 | y | 42 |
| 0 | x | 230 |

여기서 우리는 4개의 메모리를 힙에 할당했지만, 2개의 메모리를 해제했습니다. 따라서 230 과 (230) - 3 사이에 사용되지 않는 틈이 존재하게 됩니다. 이러한 일이 발생하는 것은 당신이 힙을 어떻게 관리하고 사용하는지에 달려있습니다.

여러 프로그램은 각자 다른 '메모리 할당자'(이러한 일들을 대신 관리해주는 라이브러리)를 사용할 수 있습니다. 러스트 프로그램은 [jemalloc][jemalloc]을 사용합니다.

[jemalloc]: http://www.canonware.com/jemalloc/

어쨌든, 예제로 돌아와보죠. 메모리가 힙 위에 올라갔기 때문에 Box를 할당시켰던 함수보다 오래 존재할 수 있습니다. 이번 경우에는 좀 다르긴 하지만요. 함수가 완료되면, 우리는 `main()`의 스택 프레임을 해제시켜야만 해야하죠. 그렇지만 `Box`에는 한 가지 방법이 있습니다: [Drop][drop]. `Drop`을 사용하면, `x`가 사라질 때, 힙에 할당되어있던 메모리를 먼저 해제합니다. 좋군요!

| Address | Name | Value |
|---------|------|--------|
| 1 | y | 42 |
| 0 | x | ?????? |

[drop]: drop.html
[^moving]: 소유권을 전달함으로써 메모리를 보다 오래 살아있게 만들 수 있습니다.
때때로‘상자 옮기기(moving out of the box)’라고 불립니다. 복잡한 예시들이 차후에 이것을 다룰 것입니다.

그리고 나서 스택 프레임이 사라지고, 모든 메모리가 최종적으로 해제됩니다.

# 매개변수와 빌림 (Arguments and borrowing)

지금까지 스택과 힙에 대한 간단한 예제를 살펴보았지만, 함수 인자와 빌림에 대해서는 어떨까요?
여기 작은 러스트 프로그램이 있습니다:

```rust
fn foo(i: &i32) {
let z = 42;
}

fn main() {
let x = 5;
let y = &x;

foo(y);
}
```

우리가 `main()`에 진입할 때, 메모리는 다음과 같습니다:

| Address | Name | Value |
|---------|------|-------|
| 1 | y | 0 |
| 0 | x | 5 |

`x`는 평범하게 `5`로, `y`는 `x`를 참조했습니다. 그래서 그 값은 `x`의 메모리 위치인, `0`이 됩니다.

우리가 `y`를 인자로 넘겨주며 `foo()`를 호출할 때는 어떨까요?

| Address | Name | Value |
|---------|------|-------|
| 3 | z | 42 |
| 2 | i | 0 |
| 1 | y | 0 |
| 0 | x | 5 |

스택 프레임은 지역변수뿐만 아니라, 인자에게도 마찬가지로 적용됩니다. 따라서 이 경우에 우리는 인자인 `i`와 지역변수 `z` 모두 할당해야 합니다. `i`는 인자로써 `y`의 복사본입니다. `y`의 값은 `0`이니, `i` 또한 같습니다.

이것이 어떤 값을 빌리는 게 어떤 메모리도 해제하지 않는 이유 중 하나가 됩니다: 참조 값은 단지 메모리 위치에 대한 포인터입니다. 만약 내부 메모리를 제거한다면, 잘 동작하지 않을 것입니다.

# 복잡한 예시 (A complex example)

그럼, 복잡한 프로그램으로 차근차근 해나가보죠.

```rust
fn foo(x: &i32) {
let y = 10;
let z = &y;

baz(z);
bar(x, z);
}

fn bar(a: &i32, b: &i32) {
let c = 5;
let d = Box::new(5);
let e = &d;

baz(e);
}

fn baz(f: &i32) {
let g = 100;
}

fn main() {
let h = 3;
let i = Box::new(20);
let j = &h;

foo(j);
}
```

우선, `main()`을 호출합니다:

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

`j`, `i`, `h`에 메모리를 할당하고, `i`는 힙에 할당하고 그에 따른 포인터 값을 가지게 되었습니다.

다음으로, `main()`의 끝인 `foo()`를 호출합니다:

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

`x`, `y`, `z`를 할당합니다. 인자 `x`는 호출할 때 넘겨준 `j`와 같은 값을 갖습니다. 포인터 값 `0` 주소로, `j`도 `h`를 가리키게 되었습니다.

다음으로, `foo()`는 `z`를 넘기면서 `baz()`를 호출합니다:

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 20 |
| ... | ... | ... |
| 7 | g | 100 |
| 6 | f | 4 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

`f`와 `g`를 할당합니다. `baz()`는 순식간에 작업이 끝나면 스택 프레임에서 제거됩니다:

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

다음으로, `foo()`는 `x`와 `z`를 인자로 `bar()`를 호출합니다.

| Address | Name | Value |
|----------------------|------|----------------------|
| 230 | | 20 |
| (230) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 9 |
| 9 | d | (230) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

힙의 맨 끝에서 또 하나의 값을 할당해야하므로, 230에서 1을 뺀 값의 주소가 됩니다. `1,073,741,823`라고 쓰는 것보단 쉽죠.

`bar()`의 끝에, `baz()`를 호출합니다:

| Address | Name | Value |
|----------------------|------|----------------------|
| 230 | | 20 |
| (230) - 1 | | 5 |
| ... | ... | ... |
| 12 | g | 100 |
| 11 | f | 9 |
| 10 | e | 9 |
| 9 | d | (230) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

이것으로, 가장 깊은 지점에 도달했습니다! 여기까지 따라오신 것만으로 대단합니다!

`baz()`가 완료되면, `f` 와 `g`를 제거합니다:

| Address | Name | Value |
|----------------------|------|----------------------|
| 230 | | 20 |
| (230) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 9 |
| 9 | d | (230) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

다음으로, `bar()`함수를 반환합니다. 이 경우 `Box`의 `d`는 힙에 있기 때문에, 따라서 (230) - 1에 할당된 부분도 같이 해제됩니다.

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

후에 `foo()`함수도 반환됩니다.

| Address | Name | Value |
|-----------------|------|----------------|
| 230 | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
| 1 | i | 230 |
| 0 | h | 3 |

그리고 마침내, 다른 함수들이 모두 해제된 `main()`만이 남습니다. `i`가 `Drop`된다면, 힙의 나머지 부분도 정리될 것입니다.

# 다른 언어에서는 무엇을 할까요?(What do other languages do?)

쓰레기 수집기(GC)를 가진 대부분의 언어들은 힙 할당을 기본으로 하고 있습니다. 이것은 러스트로 치자면 모든 값들이 `Box`할당되어 있다는 것을 의미합니다. 그런 결정을 한 이유는 여러가지가 있지만, 이 글의 범위에서 벗어납니다.
그러한 언어들은 쓰레기 수집기가 해제할 메모리를 관리해주기 때문에 항상 최적화될 여지가 남아있다는 단점이 있습니다. 어쨌든 다른 언어들은 스택 할당과 `Drop`을 통한 메모리 관리보다는, 쓰레기 수집기와 힙을 통해 관리를 하는 편입니다.

# 어떨때 사용해야 할까요? (Which to use?)

스택이 빠른데다가 관리하기 편하기까지 하다면, 힙은 왜 필요할까요? 가장 큰 이유는 스택 할당은 저장소 조작에 있어서 오직 LIFO(Last In First Out) 구조를 따라야 하기 떄문입니다. 힙 할당은 비교적 좀 더 일반적으로 복잡도 비용이 드는 대신 저장소에 있어서 임의적 접근이 가능합니다.

아마도 (시스템 프로그래밍에서) 스택 할당을 선택해야만 할 것입니다. 러스트 또한 스택 할당이 기본적입니다. 스택의 LIFO 모델은 근본적으로 좀 더 단순하며 예측이 쉽습니다. 그렇기 때문에 두 가지 시사점이 있습니다:런타임 효율성, 문법적 영향

## 런타임 효율성 (Runtime Efficiency)

스택에서의 메모리 관리는 간단한 일입니다: 그저 값을 쌓아서 올라가거나 내려오며, 그렇기 때문에 "스택 포인터"라고 불립니다.
힙에서의 메모리 관리는 간단하지 않습니다: 힙에 할당된 메모리는 임의의 순간에 해제될 수 있으며, 힙에 할당된 메모리 조각들은 어떤 크기도 될 수 있고, 메모리를 관리하기 위해서는 좀 더 신경써야만 합니다.

이 주제에 대해 더 자세히 알아보고 싶다면, [this paper][wilson]가 좋은 시작이 될 것입니다.


[wilson]: http://www.cs.northwcitesteern.edu/~pdinda/icsclass/doc/dsa.pdfx.ist.psu.edu/viewdoc/summary?doi=10.1.1.143.4688

## 문법적 영향 (Semantic impact)

스택 할당은 러스트 언어 그 자체 뿐만 아니라, 개발자들의 마인드 또한 바꾸어놓았습니다. LIFO 방식은 러스트 언어가 자동으로 메모리를 관리할 수 있게 해주었습니다. 여기서 자세히 논하진 않겠지만, 심지어 몇몇 특별하게 할당된 힙의 해제까지도 스택 기반 LIFO 방식으로 이루어질 수 있습니다. non-LIFO 방식은 유연하다지만, 컴파일러가 메모리가 해제될 지점을 제대로 유추하지 못하도록 하는 결과를 낳습니다. 결국 안정적인 해제를 달성하기 위해선 언어 그 자체를 넘어 바깥에 있는 규약들에 의지해야 할지도 모릅니다.(참조 카운팅인 `Rc`, `Arc`가 예시가 될 수 있습니다.)

그러한 일들이 한계에 다다르면, 힙 할당의 댓가는 상당한 런타임 비용 지불(e.g. 쓰레기 수집기) 또는 프로그래머 자신의 엄청난 노고(러스트 컴파일러가 제공하지 않는 명시적 메모리 관리)가 될 것입니다.

trait-objects
# 5.23. 트레잇 객체 (Trait Objects)

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

## 배경

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

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

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

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

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

## 정적 dispatch

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

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

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

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

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

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

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

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

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

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

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

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

## 동적 dispatch

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

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

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

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

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

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

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

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

혹은 강제하기:

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

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

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

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

### Why pointers?

Rust does not put things behind a pointer by default, unlike many managed
languages, so types can have different sizes. Knowing the size of the value at
compile time is important for things like passing it as an argument to a
function, moving it about on the stack and allocating (and deallocating) space
on the heap to store it.

For `Foo`, we would need to have a value that could be at least either a
`String` (24 bytes) or a `u8` (1 byte), as well as any other type for which
dependent crates may implement `Foo` (any number of bytes at all). There’s no
way to guarantee that this last point can work if the values are stored without
a pointer, because those other types can be arbitrarily large.

Putting the value behind a pointer means the size of the value is not relevant
when we are tossing a trait object around, only the size of the pointer itself.

### Representation

The methods of the trait can be called on a trait object via a special record
of function pointers traditionally called a ‘vtable’ (created and managed by
the compiler).

Trait objects are both simple and complicated: their core representation and
layout is quite straight-forward, but there are some curly error messages and
surprising behaviors to discover.

Let’s start simple, with the runtime representation of a trait object. The
`std::raw` module contains structs with layouts that are the same as the
complicated built-in types, [including trait objects][stdraw]:

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

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

That is, a trait object like `&Foo` consists of a ‘data’ pointer and a ‘vtable’
pointer.

The data pointer addresses the data (of some unknown type `T`) that the trait
object is storing, and the vtable pointer points to the vtable (‘virtual method
table’) corresponding to the implementation of `Foo` for `T`.


A vtable is essentially a struct of function pointers, pointing to the concrete
piece of machine code for each method in the implementation. A method call like
`trait_object.method()` will retrieve the correct pointer out of the vtable and
then do a dynamic call of it. For example
왜 포인터인가요?

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

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

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

### 표현(Representation)

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

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

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

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

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

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

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

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

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

// u8:

fn call_method_on_u8(x: *const ()) -> String {
// the compiler guarantees that this function is only called
// with `x` pointing to a u8
컴파일러는 이 함수가 u8 을 가르키는 `x` 에 대해서만 호출되도록
// 보장합니다.

let byte: &u8 = unsafe { &*(x as *const u8) };

byte.method()
}

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

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


// String:

fn call_method_on_String(x: *const ()) -> String {
// the compiler guarantees that this function is only called
// with `x` pointing to a String
컴파일러는 이 함수가 String 을 가르키는 `x` 에 대해서만 호출되도록
// 보장합니다.

let string: &String = unsafe { &*(x as *const String) };

string.method()
}

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

method: call_method_on_String as fn(*const ()) -> String,
};
```

The `destructor` field in each vtable points to a function that will clean up
any resources of the vtable’s type: for `u8` it is trivial, but for `String` it
will free the memory. This is necessary for owning trait objects like
`Box`, which need to clean-up both the `Box` allocation as well as the
internal type when they go out of scope. The `size` and `align` fields store
the size of the erased type, and its alignment requirements; these are
essentially unused at the moment since the information is embedded in the
destructor, but will be used in the future, as trait objects are progressively
made more flexible.

Suppose we’ve got some values that implement `Foo`. the explicit form of
construction and use of `Foo` trait objects might look a bit like (ignoring the
type mismatches: they’re all just pointers anyway
각 vtable 의 `destructor` 필드는 vtable 의 타입에 대한 리소스들을 정리 하는데 사용되는 함수를 가르킵니다, `u8` 은 사소하지만, `String` 인 경우는 메모리를 해제 할 것입니다. 이것은 `Box` 와 같이 트레잇 객체를 소유하는 경우, `Box` 에 대한 할당과 스코프를 벗어났을 때 내부 타입을 정리 하기 위해 필요합니다. `size` 와 `align` 필드들은 지워진 타입에 대한 크기와 정렬(alignment) 요구사항들을 저장합니다; 이것들은 기본적으로 소멸자(destructor)에 포함되기 때문에 지금은 사용되지 않지만, 트레잇 객체는 계속해서 더 유연하게 만들어 지기 때문에 나중에는 사용될 것 입니다.

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

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

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

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

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

// y.method();
(y.vtable.method)(y.data);
```
variable-bindings
# 5.1. 변수 바인딩 (Variable Bindings) - 9100%

사실상 모든 'Hello World’가 아닌 Rust 프로그램은 *변수 바인딩*을 사용합니다. 다음을 보세요.

```rust
fn main() {
let x = 5;
}
```

각 예제마다 `fn main() {`을 넣는것은 쫌 귀찮기 때문에 이후로는 생략할 것입니다. 특별한 언급이 없다면, `main()` 함수를 수정하시면 됩니다. 그렇지 않는다면, 에러가 날 것입니다.

이것은 많은 언어들에서, *변수(variable)*라고 합니다. 그렇지만 Rust의 변수 바인딩은 몇가지 꼼수를 가지고 있습니다. 예를 들어, 변수 이름뿐만 아니라 `let` 식이 ‘[패턴][pattern]’의 왼쪽에 올 수 있습니다. 다음과 같이 할 수 있다는 뜻입니다.

```rust
let (x, y) = (1, 2);
```

이 식이 평가되고 나면, `x`는 1이 되고, `y`는 2가 됩니다. 패턴은 진짜로 강력하고, 이 책에선 [자체 섹션][pattern]도 있습니다. 우리는 아직 이 기능이 필요하지 않기 때문에, 진도를 나아가기 위해 마음 한구석에만 잘 담아둡시다.

[pattern]: patterns.html

Rust는 정적 타입 언어입니다. 그 말은 앞에 타입을 명시해줘야 한다는 것을 의미하고, 컴파일중에 검증됩니다. 하지만 왜 첫번째 예제는 컴파일 될까요? 흠, Rust는 ‘타입 추론(type inference)’ 이라고 하는 기능을 가지고 있습니다. 무언가의 타입을 알아낼 수 있다면, Rust는 타입을 주는 것을 필요로 하지 않습니다.

우리는 원한다면 타입을 추가할 수 있습니다. 타입은 콜론(`:`) 뒤에 옵니다.

```rust
let x: i32 = 5;
```

제가 여러분께 교실의 다른 친구들에게 큰 소리로 읽어달라고 한다면, "`x`는 `i32` 타입과 `five` 값에 바인딩되었다."라고 할 것입니다.

이 경우, `x`를 32 비트 부호있는 정수로 선택했습니다. Rust는 서로 다른 많은 기본 정수 타입을 가지고 있습니다. 부호있는 정수는 `i`로, 부호없는 정수는 `u`로 시작합니다. 가능한 정수 크기는 8, 16, 32, 64 비트입니다.

이후 예제부터, 타입에 대해 주석을 달지도 모르겠네요. 이렇게요.

```rust
fn main() {
let x = 5; // x: i32
}
```

이 주석이 문법과 유사한 것은 `let`과 함께 쓰인다는 정도입니다. 이런 식의 주석을 포함하는 것은 관용적인 Rust 언어는 아니지만, 어떤 타입이 추론되었는지 이해하기 쉽게 해줍니다.

기본적으로, 바인딩은 *불변(immutable)* 입니다. 이 코드는 컴파일 안됩니다.

```rust,ignore
let x = 5;
x = 10;
```

이런 에러를 토해낼 겁니다.

```text
error: re-assignment of immutable variable `x`
x = 10;
^~~~~~~
```

변할수 있도록 바인딩하길 원한다면, `mut`를 사용하면 됩니다.

```rust
let mut x = 5; // mut x: i32
x = 10;
```

바인딩이 기본적으로 불변인 것이 하나의 이유만 있는것은 아니지만, 우리는 Rust의 기본적인 관점중 하나에 대해 생각해볼 수 있습니다. 바로 안전성이죠. 만약 `mut`라고 적는 것을 까먹었다면, 컴파일러는 알아챌 것이고, 여러분이 바꿀 의도가 없었는데 무언갈 바꾸려고 했다고 알려줍니다. 바인딩이 기본적으로 변경 허용이었다면, 컴파일러는 이를 알려줄 수가 없을 것입니다. 여러분이 _정말_ 변경을 의도한다면, 방법은 간단합니다. `mut`를 적으세요.

다른 좋은 이유는 가능한 변경되는 상태를 피할수 있다는 것이지만, 이 문서의 범위를 벗어나는 내용입니다. 일반적으로, Rust에서는 노골적인 변경을 피하는 것이 더 선호됩니다. 때때로 이 말은, 변경은 필요로 할때만, 그래서 그래서 금지하지는 않습니다.

이제 다시 바인딩으로 돌아가봅시다. Rust의 변수 바인딩은 다른 언어와는 하나 이상의 차이점을 가지고 있습니다. 바인딩은 여러분이 그것을 사용하기 전에 값과 함께 초기화되어야 합니다.

한번 해봅시다. `src/main.rs` 파일을 다음처럼 수정해 보세요.

```rust
fn main() {
let x: i32;

println!("Hello world!");
}
```

빌드하기 위해 커맨드 라인에서 `cargo build`를 할 수 있습니다. 경고가 표시되겠지만, 여전히 "Hello, world!"를 출력할 것입니다.

```text
Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
src/main.rs:2:9: 2:10 warning: unused variable: `x`, #[warn(unused_variable)] on by default
src/main.rs:2 let x: i32;
^
```

Rust는 변수 바인딩을 하지 않았다고 경고를 합니다만, 우리는 그것을 사용하지 않기 때문에, 해롭지도, 잘못되지도 않았습니다. 그러나 `x`를 사용한다면 상황이 다릅니다. 한번 해보죠. 다음과 같이 프로그램을 수정해보세요.

```rust,ignore
fn main() {
let x: i32;

println!("The value of x is: {}", x);
}
```

그리고 빌드를 시도하면 에러가 표시될 것입니다.

```bash
$ cargo build
Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world)
src/main.rs:4:39: 4:40 error: use of possibly uninitialized variable: `x`
src/main.rs:4 println!("The value of x is: {}", x);
^
note: in expansion of format_args!
:2:23: 2:77 note: expansion site
:1:1: 3:2 note: in expansion of println!
src/main.rs:4:5: 4:42 note: expansion site
error: aborting due to previous error
Could not compile `hello_world`.
```

Rust는 초기화되지 않은 값을 사용하는 것을 허용하지 않습니다. 다음으로, `println!`에서 발생한 일에 대해 다뤄봅시다.

출력할 문자열에 두 개의 중괄호(`{}`, 콧수염(moustaches)이라고 부르기도 합니다.)가 포함되어 있다면, Rust는 어떤 종류의 값을 삽입하라는 요청으로 해석할 것입니다. *문자열 삽입(String interpolation)*은 컴퓨터 과학 용어로 "문자열 중간에 붙히다(stick in the middle of a string)."라는 의미입니다. 쉼표 뒤의, `x`는, 삽입할 값을 가리킵니다. 복수개의 인자를 넘긴다면, 쉼표는 함수와 매크로에 넘기는 인자를 구분하는데 쓰입니다.

When you just use the curly braces, Rust will attempt to display the
value in a meaningful way by checking out its type. If you want to specify the
format in a more detailed manner, there are a [wide number of options
available][format]. For now, we'll just stick to the default:
integers aren't very complicated to print.
중괄호를 사용하면, 러스트는 그것의 타입을 확인해서 값을 명확히 드러내도록 해줄 것입니다. 하지만 만약 더 구체적인 정보를 명시하고 싶으면, [많은 종류의 옵션][format]이 존재합니다. 정수는 그다지 복잡하게 출력되지 않기 때문에, 지금부터는 그냥 기본값으로 가도록 하죠:

[format]: ../std/fmt/index.html
while-loops
Deleted file