Merge changes from master into djKooks

djKooks authored
revision 51074cafeb1866a2518df81c121f06cd1f346c9a
About
### Rust 문서 한글화 프로젝트

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

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

- 한글화 미완료 챕터 목록(작성중)
- [4.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) - 50%
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
advanced-linking.md
if-let.md
trait-objects.md
closures.md
ufcs.md
crates-and-modules.md
concordance.md
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) - 100%

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

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![1, 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
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 result = thread::spawn(move || {
panic!("oops!");
}).join();

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

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

문서화는 어떤 소프트웨어 프로젝트이든 중요한 부분이고, 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 t

T
he first thing
to notice about this annotation: is that `//` 대신에 `///`를 사용합니다. 세 개의 슬래시는 문서 주석을 나타냅니다.

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

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

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

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

To write some Rust code in a comment, use the triple graves:주석 내에 Rust 코드를 적고 싶다면, 세 개의 역따옴표를 사용하세요.

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

If you want something that's not Rust code, you can add an annotation:Rust 코드가 아니라면, 언어 이름을 표기할 수 있습니다.

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

This will highlight according to whatever language you're showing off.
If you're just showing plain text, choose `text`.

It's important to choose the correct annotation here, because `rustdoc` uses it
in an interesting way:
표기한 언어에 따라 구문강조될 것입니다. 단순히 텍스트를 보여주려면, `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.

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

Let's discuss our sample example documentation:샘플 예제 문서화로 논의해봅시다.

```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 = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://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
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",
}
}

fn main() {
std::io::println(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)을 이용합니다.
ffi
# 4.8. 외부 함수 인터페이스 (Foreign Function Interface) - 60%

# 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 includes type aliases and function definitions for the C
standard library in the `libc` module, and Rust links against `libc` and `libm`
by default.

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

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() {}
```
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`, 메소드, 연결된 함수, 외부 크레이트 사용하기 등등. 다음 프로젝트에서는 더 많은 것을 다룰 것입니다.
loops
# Loops
readme
# 1. 소개(Introduction) - 100%

환영합니다! 이 책은 당신에게 [Rust 프로그래밍 언어][rust]에 대해 알려줄 것입니다. Rust는 세가지 목표(안전성, 속도, 병행성)에 초점을 맞춘 시스템 프로그래밍 언어입니다. Rust는 가비지 콜렉터 없이 이러한 목표를 달성하고 있고, 때문에 다른 언어들이 그다지 훌륭하지 못한 몇 가지 부분에서 강세를 보입니다. 예를 들어 다른 언어에 내장(_embedding_)시키는 일, 특정한 공간/시간 제약을 갖는 프로그램을 작성하는 일, 장치 드라이버나 운영 체제 등의 로우 레벨 코드를 작성하는 일 등이죠. Rust는 컴파일 타임에 이루어지는 몇 가지 안정성 체크를 통해 런타임 오버헤드를 발생시키지 않으면서도 이러한 목표를 가진 현존하는 언어들보다 뛰어난 성과를 보여줍니다. 또한, Rust는 고수준 언어들이 제공하는 것과 비슷하게 느껴지는 추상화를 제공하면서도 '무비용 추상화_zero-cost abstraction_'을 달성하고자 합니다. 그러면서도, 많은 로우 레벨 언어들처럼 정밀한 제어도 가능케 하죠.

[rust]: http://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에 영향을 준 문헌.

[gs]: getting-started.md
[lr]: learn-rust.md
[er]: effective-rust.md
[ss]: syntax-and-semantics.md
[nr]: nightly-rust.md
[gl]: glossary.md
[ar]: academic-research.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.htmlmd
[macro]: macros.htmlmd
[heap]: the-stack-and-the-heap.htmlmd

앞서 '소유권'이 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.htmlmd

세 번째 줄을 추가해 봅시다. 겉보기에는 별 문제 없어 보이는 코드입니다만, 이는 컴파일러 오류를 유발합니다.

```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.html#move-semantics

만약 정말로 참조를 사용하고 싶다면, 또 다른 선택지가 필요합니다. 어떤 참조에 대한 변경이 시행되기 전에 반드시 그것이 유효 범위를 벗어나도록 만드는거죠. 다음과 같이 말입니다.


```rust
fn main() {
let mut x = vec!["Hello", "world"];

{
let y = &x[0];
}

x.push("foo");
}
```

우리는 추가적인 중괄호 쌍을 이용해 안쪽에 새로운 유효 범위를 만들었습니다. `y`는 우리가 `push()` 를 호출하기 전에 유효 범위를 벗어날 것이므로 문제는 발생하지 않겠죠.


이렇듯 소유권 시스템은 단지 댕글링 포인터뿐만 아니라, 반복자 무효화_iterator invalidation_, 동시성_concurrency_ 등 연관된 모든 문제점들을 예방하는데에 유용합니다.
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