제목 및 링크 업데이트

sarojaba authored
revision 8f417f69f065b8c97a7f00ef4afe50d40ab5d232
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.htmlmd
[lr]: learn-rust.htmlmd
[er]: effective-rust.htmlmd
[ss]: syntax-and-semantics.htmlmd
[nr]: nightly-rust.htmlmd
[gl]: glossary.htmlmd
[ar]: academic-research.htmlmd

이 소개 항목을 읽고 나서 당신은 '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()` 를 호출하기 전에 유효 범위를 벗어날 것이므로 문제가 없습니다.


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