Merge changes from master into SoonBin

SoonBin authored
revision bdffcd4f9578e2c204d46339e1459d491c223133
About
### Rust 문서 한글화 프로젝트

- 본 프로젝트는 Mozilla에서 개발한 Rust 언어의 문서를 한글화하는 프로젝트입니다.
- 현재 작업중인 문서는 [Book 1.2.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%
conditional-compilation
# 4.3. 조건부 컴파일 (Conditional Compilation) - 370%

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

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

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

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

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

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

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

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

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

As for how to enable or disable these switches, if you’re using Cargo,
they get set in the [`[features]` section][features] of your `Cargo.toml`:
만약 Cargo를 사용한다면, `Cargo.toml`의 [`[features]` section][features] 속성값을 통해 이 기능들을 사용할 지 여부를 설정할 수 있습니다.

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

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

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

When you do this, Cargo passes along a위와 같이 구현하면, Cargo는 flag to값들을 `rustc`:로 전달합니다.

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

The sum of these `cfg` flags will determine which ones get activated, and
therefore, which code gets compiled. Let’s take this code:
이렇게 정의된 `cfg` flag값들은 어떤 속성들이 활성화 되어야 하고, 이를 통해 어떤 코드들이 컴파일 되어야 하는지를 결정하게 됩니다. 아래 코드를 살펴보도록 하겠습니다.

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

If we compile it with위 코드를 `cargo build --features "foo"`, it will send the로 컴파일 할 경우, `--cfg
feature="foo"` flag to `rustc`, and the output will have the `mod foo` in it.
If we compile it with a regular `cargo build`, no extra flags get passed on,
and so, no `foo` module will exist
플래그값을 `rustc`로 전달하고 결과물에는 `mod foo`가 포함되게 됩니다. 반대로, 일반적인 `cargo build`로 컴파일할 경우에는 어떤 flag값도 전달되지 않으며, 따라서 `foo`모듈도 존재하지 않습니다.

# cfg_attr

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

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

Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwise.

# cfg!

The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
elsewhere in your code, too:

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

[compilerplugins]: compiler-plugins.html

These will be replaced by a `true` or `false` at compile-time, depending on the
configuration settings.
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 the first thing
to notice about this annotation: `//` 대신에 `///`를 사용합니다. 세 개의 슬래시는 문서 주석을 나타냅니다.

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

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

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

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

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

오류가 날 것입니다.

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

이 [불행한 오류](https://github.com/rust-lang/rust/issues/22547)는 맞습니다. documentation comments apply to the thing after them, and there's no
thing after that last comment.

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

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

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

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

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

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

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

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

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

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

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

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

Third, `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() {}
```
effective-rust
# 4. 효과적인 Rust (Effective Rust) - 100%

여러분은 지금까지 Rust 코드를 작성하는 방법을 일정 부분 배웠습니다. 하지만 *아무런그냥* Rust 코드를 작성하는 것과 *좋은* Rust 코드를 작성하는 것은 차이가 있습니다.

이 단원은 여러분의 Rust 실력을 더 높은 수준으로 향상시켜 비교적 독립적인 튜토리얼들로 구성되어 있습니다. 일반적 패턴들과 표준 라이브러리 기능들을 소개시켜 드릴 겁니다. 다음 단원들은 어떤 순서든 상관없이 읽으셔도 됩니다.
functions
# 5.2. 함수 (Functions) - 5100%

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

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

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

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

이제, 인자를 받아볼까요? 여기 숫자를 출력하는 함수가 있습니다.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

그러면, 에러가 표시될 것입니다.

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

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

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

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

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

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

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

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

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

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

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

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

```rust
let mut y = 5;

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

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

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

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

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

## 미리 반환 (Early returns)

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

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

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

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

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

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

## Diverging functions

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

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

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

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

```should_panic
# fn diverges() -> ! {
# panic!("This function never returns!");
# }
let x: i32 = diverges();
let x: String = diverges();
```
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_ 등 연관된 모든 문제점들을 예방하는데에 유용합니다.