Updated readme.md

heejongahn authored
revision 3e48cfd248f1e54d4f232d8a67021a9f97acffd4
readme
# 1. 소개(Introduction) - 100%

환영합니다! 이 책은 당신에게 [Rust 프로그래밍 언어][rust]에 대해 알려줄 것입니다. Rust는 세가지 목표(안전성, 속도, 병행성)에 초점을 맞춘 시스템 프로그래밍 언어입니다. 가비지 컬렉터를 가지지 않고 이 목표들을 지속하고 있습니다. 모든 언어들의 다양한 활용을 만족하는 유용한 언어를 만드는 것은 좋지 않습니다. 다른 언어들에 내포되는 것, 프로그램에 특정 공간과 시간이 필요한 것, 디바이스 드라이버와 운영체제와 같이 낮은 레벨의 코드를 작성하는 것. 현존 언어들에, 모든 데이터 경합을 제거하며, 실행 중 부하가 발생하지 않도록 컴파일 중 다양한 안전성 확인을 가지는 영역에 초점을 맞춰 발전시킵니다. 또한 Rust는 추상화들 중 어떤것들은 고수준의 언어의 추상화의 느낌이 나는 것에도 불구하고 ‘비용없는 추상화’를 이루는데 초점을 두고 있습니다. 그럼에도, Rust는 여전히 저수준 언어에서 하는 것같은 정밀한 제어를 허용합니다.

[rust]: http://rust-lang.org

“Rust 프로그래밍 언어”는 일곱 단원으로 구분됩니다. 이 소개는 첫번째 단원입니다. 다음 단원들입니다.

* [시작하기(Getting started)][gs] - Rust 개발을 위한 컴퓨터 환경 구축.
* [Rust 배우기(Learn Rust)][lr] - 작은 프로젝트를 통해 Rust 프로그래밍을 배움.
* [효과적인 Rust(Effective Rust)][er] - 훌륭한 Rust 코드를 작성하기 위한 더 높은 수준의 개념들.
* [문법과 의미(Syntax and Semantics)][ss] - Each bit of Rust, broken down into small chunks.
* [실험적 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`를 변경 가능한 변수로 만들었습니다. Rust에서는 변수 결합은 기본적으로 변경할 수 없습니다. 우리는 나중에 이 벡터를 예제 속에서 변경할 것입니다.

여기서 우리가 타입을 기술할 필요가 없다는 것을 짚어보는 것도 좋겠습니다. Rust는 정적 타이핑을 하지만, 우리는 타입을 명시적으로 적을 필요가 없습니다. 정적 타이핑의 강력함과 타입을 장황하게 적어야 하는 불편함 사이에서 균형을 잡기 위해, Rust는 타입 추론(type inference) 기능을 가지고 있습니다.

Rust는 힙 할당보다 스택 할당을 선호합니다. `x`는 스택 위에 바로 할당됩니다. 그러나, `Vec` 타입은 벡터의 요소들을 저장하기 위한 공간을 힙에 할당합니다. 만약 여러분이 이러한 차이점에 익숙하지 않다면 일단 여기에서는 무시해도 좋습니다. 아니면 [‘스택과 힙’][heap] 문서를 참고할 수 있습니다. 시스템 프로그래밍 언어인 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`를 변경 가능한 변수로 만들었습니다. Rust에서는 변수 바인딩은 기본적으로 변경할 수 없습니다. 우리는 나중에 이 벡터를 변경하는 예제도 살펴보죠.

타입을 명시적으로 기술하지 않았다는 것도 주목할만한 점이죠. Rust는 정적 타입 언어지만, 타입을 꼭 명시적으로 적을 필요가 없습니다. 정적 타이핑의 강력함과 타입을 장황하게 적어야 하는 불편함 사이에서 균형을 잡기 위해, Rust는 타입 추론(type inference) 기능을 가지고 있습니다.

Rust는 힙 할당보다 스택 할당을 선호합니다. `x`는 스택 위에 바로 할당됩니다. 그러나, `Vec` 타입은 벡터의 요소들을 저장하기 위한 공간을 힙에 할당합니다. 만약 무슨 차이인지 모르겠다면, 일단 여기에서는 무시해도 좋습니다. 아니면 [‘스택과 힙’][heap] 문서를 참고하셔도 좋구요. 시스템 프로그래밍 언어로서 Rust는 메모리를 어떻게 할당할 것인가에 대한 제어권을 사용자에게 제공합니다. 그러나 우리는 이제 막 시작하는 참이고, 그게 그렇게 중요한 일은 아니겠죠
.

[var]: variable-bindings.html
[macro]: macros.html
[heap]: the-stack-and-the-heap.html

앞서서 우리는 '소유권'이 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.html

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

```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`는 최신화되지 않으므로, '댕글링 포인터'를 갖게 된다는 것입니다. 이는 나쁜 현상입니다. 이 경우 `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]: move-semantics.html

만약 정말로 참조가 필요하다면, 또 다른 선택지가 필요합니다. 반드시 참조의 유효 범위가 변경을 수행하기 이전에 벗어날 수 있도록 하는 것입니다. 이것은 다음과 같습니다.


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

{
let y = &x[0];
}

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

우리는 또 다른 중괄호 쌍으로 안쪽에 유효 범위를 만들었습니다. `y`는 우리가 `push()` 를 호출하기 전에 유효 범위를 벗어날 것이므로 문제가 없습니다.


이 소유권 개념은 댕글링 포인터뿐만 아니라, 반복자 무효화, 병렬성 등 연관된 모든 문제점들을 예방할 수 있습니다.