Merge changes from master into ziriso

ziriso authored
revision 0b97898cd725ffe33e403d29d87024a28179bc4d
concordance
# 9. 용어 색인 (Concordance)

* 이 페이지는 Rust 한글화 프로젝트에서 사용되는 용어들의 영문과 국문을 일대일로 표기해놓은 가이드입니다.
* 번역하시면서 새로운 용어가 나오면 추가해주세요. 좀 더 적절한 대체 용어가 있다면 구성원들의 의견을 모아 반영합니다.
* 알파벳 순으로 표기합니다.
* [정보통신용어사전](http://word.tta.or.kr/terms/terms.jsp), [텀즈](http://www.terms.co.kr/), [Joinc 컴퓨터 용어사전](http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/12), [정보통신기술용어해석](http://www.ktword.co.kr/) 등을 참조하세요.

## A - G

* address - 주소
* allocate - 할당하다
* binding - 바인딩
* borrowing - 빌림
* Cargo - 카고
* compile - 컴파일
* dynamic language - 동적 언어
* exterior mutability - 외적 가변성
* Field-level mutability - 필드 단위 가변성
* function - 함수
* garbage collector - 가비지 콜렉터

## H - N

* heap - 힙
* immutable - 변경할 수 없는, 불변
* immutable - 불변
* input - 입력
* interior mutability - 내적 가변성
* iterator
* LIFO
* macro - 매크로
- 반복자
* lifetime - 수명
* lifetime elision - 수명의 생략
* LIFO - LIFO
* macro - 매크로
* mutable - 변경할 수 있는

* mutable - 가변
* mutability - 가변성

## O - Z

* output - 출력
* ownership - 소유권
* pointer - 포인터
* Rust - 러스트
* stackemantics - 스택구문
* semanticsigniture - 시그니처
* stack - 스택

* syntax - 의미
* testing- 테스팅
* variable - 변수
* vector - 벡터
* verification - 검증
* zero-cost abstractions - 무비용 추상화
lifetimes
# 5.10. 수명 (Lifetimes)

This guide is one of three presenting Rust’s ownership system. This is one of
Rust’s most unique and compelling features, with which Rust developers should
become quite acquainted. Ownership is how Rust achieves its largest goal,
memory safety. There are a few distinct concepts, each with its own chapter:

* [ownership][ownership], the key concept
* [borrowing][borrowing], and their associated feature ‘references’
* lifetimes, which you’re reading now

These three chapters are related, and in order. You’ll need all three to fully
understand the ownership system.

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

# Meta

Before we get to the details, two important notes about the ownership system.

Rust has a focus on safety and speed. It accomplishes these goals through many
‘zero-cost abstractions’, which means that in Rust, abstractions cost as little
as possible in order to make them work. The ownership system is a prime example
of a zero-cost abstraction. All of the analysis we’ll talk about in this guide
is _done at compile time_. You do not pay any run-time cost for any of these
features.

However, this system does have a certain cost: learning curve. Many new users
to Rust experience something we like to call ‘fighting with the borrow
checker’, where the Rust compiler refuses to compile a program that the author
thinks is valid. This often happens because the programmer’s mental model of
how ownership should work doesn’t match the actual rules that Rust implements.
You probably will experience similar things at first. There is good news,
however: more experienced Rust developers report that once they work with the
rules of the ownership system for a period of time, they fight the borrow
checker less and less.

With that in mind, let’s learn about lifetimes.

# Lifetimes

Lending out a reference to a resource that someone else owns can be
complicated. For example, imagine this set of operations:

- I acquire a handle to some kind of resource.
- I lend you a reference to the resource.
- I decide I’m done with the resource, and deallocate it, while you still have
your reference.
- You decide to use the resource.

Uh oh! Your reference is pointing to an invalid resource. This is called a
dangling pointer or ‘use after free’, when the resource is memory.

To fix this, we have to make sure that step four never happens after step
three. The ownership system in Rust does this through a concept called
lifetimes, which describe the scope that a reference is valid for.

When we have a function that takes a reference by argument, we can be implicit
or explicit about the lifetime of the reference:

```rust
// implicit
fn foo(x: &i32) {
}

// explicit
fn bar<'a>(x: &'a i32) {
}
```

The `'a` reads ‘the lifetime a’. Technically, every reference has some lifetime
associated with it, but the compiler lets you elide them in common cases.
Before we get to that, though, let’s break the explicit example down:

```rust,ignore
fn bar<'a>(...)
```

This part declares our lifetimes. This says that `bar` has one lifetime, `'a`.
If we had two reference parameters, it would look like this:

```rust,ignore
fn bar<'a, 'b>(...)
```

Then in our parameter list, we use the lifetimes we’ve named:

```rust,ignore
...(x: &'a i32)
```

If we wanted an `&mut` reference, we’d do this:

```rust,ignore
...(x: &'a mut i32)
```

If you compare `&mut i32` to `&'a mut i32`, they’re the same, it’s just that
the lifetime `'a` has snuck in between the `&` and the `mut i32`. We read `&mut
i32` as ‘a mutable reference to an i32’ and `&'a mut i32` as ‘a mutable
reference to an `i32` with the lifetime `'a`’.

You’ll also need explicit lifetimes when working with [`struct`][structs]s:
이 가이드는 러스트의 소유권 시스템을 설명하는 세 가이드 중 하나입니다. 이는 러스트의 가장 고유하면서 매력적인 동시에 러스트 개발자들이 반드시 친숙해져야 하는 특징입니다. 소유권을 통해 러스트는 스스로의 가장 거대한 목표인 메모리 안정성을 성취해냅니다. 관련된 몇가지 개념들이 있는데, 각각을 설명하는 장이 존재합니다. 다음과 같죠:

* 핵심 개념인 [소유권][ownership]
* [빌림][borrowing], 그리고 관련된 특징인 '참조'
* 여러분이 지금 읽고 계시는 수명

이 세 장들은 연관되어 있고, 순서대로 작성되어 있습니다. 소유권 시스템을 이해하기 위해선 세 장을 모두 필요로 할 것입니다.

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


## 개괄

세부사항을 살펴보기 전에, 소유권 시스템에 관한 두 가지 중요한 점을 짚고 넘어가겠습니다.

러스트는 안정성과 속도에 초점을 맞추고 있고, 이러한 목표들을 많은 '무비용 추상화 _zero-cost abstraction_'들을 통해 이루어냅니다. 다시 말해, 러스트에서 추상화는 그것이 작동하기 위해 필요한 최소한의 비용만을 필요로 합니다. 소유권 시스템은 무비용 추상화의 대표적인 예입니다. 이 가이드에서 이야기할 모든 분석들은 _컴파일 타임 내에 _이루어집니다. 이러한 기능들을 사용하기 위해 런타임에서 비용을 치를 필요는 없다는 이야기죠.

하지만, 이 시스템 역시 치뤄야할 비용은 있기 마련인데, 바로 학습 곡선입니다. 러스트를 처음 접하는 많은 사용자들은 작성자는 아무 문제가 없다고 생각하는 프로그램을 러스트 컴파일러가 컴파일하기 거부하는 현상에 맞닥뜨립니다. 우리가 '소유권 검사기와의 싸움'이라고 부르는 현상이죠. 이는 보통 소유권이 어떻게 동작해야 하는 지에 대한 프로그래머의 생각과 실제 러스트가 구현하는 규칙들이 다르기 때문에 발생합니다. 이 글을 읽고 있는 당신도 처음엔 비슷한 경험을 할지 모릅니다. 좋은 소식은, 이러한 소유권 시스템 규칙들과 함께 작업을 하면 할수록 소유권 검사기와 싸울 일은 점점 적어진다고 다수의 숙련된 러스트 개발자들이 말한다는 거죠.

그걸 명심하시고, 수명에 대해 배워봅시다.

# 수명

소유권자는 따로 있는 리소스에 대한 참조를 빌려주는 일은 꽤 복잡해질 수 있습니다. 예를 들어, 다음 일련의 명령을 생각해보세요.

- 제가 어떤 리소스에 대한 제어권을 얻습니다.
- 그리고 그 리소스에 대한 참조를 당신에게 빌려주는거죠.
- 당신이 그 참조를 아직 들고 있는 시점에서, 제가 그 리소스로 할 일을 마쳤다고 판단하고, 해당 리소스의 할당을 해제합니다.
- 그 후, 당신이 그 리소스를 사용하기로 마음먹습니다.

아이구 이런! 당신의 참조는 이제 유효하지 않은 리소스를 가리키고 있습니다. 그 리소스가 메모리인 경우에, 이러한 현상은 댕글링 포인터(dangling pointer) 혹은 '해제 이후의 사용(use after free)'라고 불립니다.

이걸 고치기 위해, 우리는 위의 예제에서 3번째 단계가 일어난 후에는 4번째 단계가 절대 일어나지 않을 것을 보장해 줄 필요가 있겠죠. Rust의 소유권 시스템은 수명(lifetime)이라는 개념을 통해 그 일을 해냅니다. 수명은 어떤 참조가 어떤 유효 범위(scope)안에서만 유효한지를 나타냅니다.

참조를 인자로 받는 함수가 있을 때, 그 참조의 수명을 명시적으로, 혹은 암묵적으로 나타낼 수 있습니다.

```rust
// implicit
fn foo(x: &i32) {
}

// explicit
fn bar<'a>(x: &'a i32) {
}
```

`'a`는 '수명 a'라고 읽습니다. 엄밀히 말하자면, 모든 참조는 자신과 관련된 수명을 가지고 있지만, 컴파일러가 있기 때문에 보통의 경우에는 당신이 그것을 굳이 언급하지 않아도 됩니다. 그 얘기를 좀 더 자세히 하기 전에, 일단 이 명시적 예제를 살펴보죠.

```rust,ignore
fn bar<'a>(...)
```

이 부분은 수명들을 선언하는 부분입니다. `bar`라는 함수는 `'a`라고 불리는 하나의 수명을 가지고 있다고 말이죠. 만약 참조 매개변수가 두 개였다면, 아마 다음과 같았을 겁니다.

```rust,ignore
fn bar<'a, 'b>(...)
```

그 다음 우리의 매개변수 리스트에서, 우리가 명명한 수명들을 사용합니다.

```rust,ignore
...(x: &'a i32)
```

만약 `&mut` 참조를 원했다면, 다음과 같았겠죠.

```rust,ignore
...(x: &'a mut i32)
```

`&mut i32`와 `&'a mut i32`는 `&`와 `mut i32` 사이에 수명 `a`가 끼어들었다는 것을 제외하곤 동일합니다. 각각 `&mut i32`는 '`i32`로의 변경 가능한 참조', `&'a mut i32`는 '`'a'`의 수명을 갖는 `i32`로의 변경 가능한 참조' 라고 읽습니다.

[구조체(`struct`)][structs]를 사용할 때에도 명시적 수명이 필요합니다.


```rust
struct Foo<'a> {
x: &'a i32,
}

fn main() {
let y = &5; // this is the same as `let _y = 5; let y = &_y;`
let f = Foo { x: y };

println!("{}", f.x);
}
```

[structs]: structs.html

As you can see, `struct`s can also have lifetimes. In a similar way to functions위에서 볼 수 있듯, `struct` 역시 수명을 가질 수 있습니다. 함수와 비슷한 방식인데,

```rust
struct Foo<'a> {
# x: &'a i32,
# }
```

declares a lifetime, and위와 같이 수명을 선언하고,

```rust
# struct Foo<'a> {
x: &'a i32,
# }
```

uses it. So why do we need a lifetime here? We need to ensure that any reference
to a `Foo` cannot outlive the reference to an `i32` it contains.

## Thinking in scopes

A way to think about lifetimes is to visualize the scope that a reference is
valid for. For example:
사용하는거죠. 여기서는 수명이 왜 필요한걸까요? `Foo`로의 참조가 그 안에 담겨있는 `i32`로의 참조보다 더 오래 살 수 없다는 것을 보장할 필요가 있기 때문입니다.

## 유효 범위에 대해 생각하기

수명에 대해 좀 더 다뤄보기 위해 어떤 참조가 의미를 갖는(유효한) 유효 기간을 시각화해보죠. 다음과 같이요.


```rust
fn main() {
let y = &5; // -+ y goes into scope
// |
// stuff // |
// |
} // -+ y goes out of scope
```

Adding in our `Foo`:앞서 언급한 `Foo`를 집어넣어 볼까요?

```rust
struct Foo<'a> {
x: &'a i32,
}

fn main() {
let y = &5; // -+ y goes into scope
let f = Foo { x: y }; // -+ f goes into scope
// stuff // |
// |
} // -+ f and y go out of scope
```

Our `f` lives within the scope of `y`, so everything works. What if it didn’t?
This code won’t work:
`f`는 `y`의 유효 기간 내에서만 살아있고, 따라서 아무런 문제가 없습니다. 하지만 만약 그렇지 않다면 어떨까요? 다음의 코드는 제대로 작동하지 않습니다.

```rust,ignore
struct Foo<'a> {
x: &'a i32,
}

fn main() {
let x; // -+ x goes into scope
// |
{ // |
let y = &5; // ---+ y goes into scope
let f = Foo { x: y }; // ---+ f goes into scope
x = &f.x; // | | error here
} // ---+ f and y go out of scope
// |
println!("{}", x); // |
} // -+ x goes out of scope
```

Whew! As you can see here, the scopes of `f` and `y` are smaller than the scope
of `x`. But when we do `x = &f.x`, we make `x` a reference to something that’s
about to go out of scope.

Named lifetimes are a way of giving these scopes a name. Giving something a
name is the first step towards being able to talk about it.

## 'static

The lifetime named ‘static’ is a special lifetime. It signals that something
has the lifetime of the entire program. Most Rust programmers first come across
`'static` when dealing with strings:

```rust
let x: &'static str = "Hello, world.";
```

String literals have the type `&'static str` because the reference is always
alive: they are baked into the data segment of the final binary. Another
example are globals:

```rust
static FOO: i32 = 5;
let x: &'static i32 = &FOO;
```

This adds an `i32` to the data segment of the binary, and `x` is a reference
to it.

## Lifetime Elision

Rust supports powerful local type inference in function bodies, but it’s
forbidden in item signatures to allow reasoning about the types just based in
the item signature alone. However, for ergonomic reasons a very restricted
secondary inference algorithm called “lifetime elision” applies in function
signatures. It infers only based on the signature components themselves and not
based on the body of the function, only infers lifetime parameters, and does
this with only three easily memorizable and unambiguous rules. This makes
lifetime elision a shorthand for writing an item signature, while not hiding
away the actual types involved as full local inference would if applied to it.

When talking about lifetime elision, we use the term *input lifetime* and
*output lifetime*. An *input lifetime* is a lifetime associated with a parameter
of a function, and an *output lifetime* is a lifetime associated with the return
value of a function. For example, this function has an input lifetime:
이쿠! 보시다시피, `f`와 `y`의 유효 범위는 `x`의 그것보다 짧습니다. 그럼에도 불구하고 `x = &f.x`를 통해 `x`를 이제 곧 유효 범위를 나가는 녀석을 가리키는 참조로 만들었죠.

명명된 수명(named lifetime)을 통해 유효 범위에게 이름을 줄 수 있습니다. 어떤 것에 대해 이야기하기 위해선 일단 이름부터 매겨야겠죠.

## 'static

'static'이라는 이름의 수명은 특별한 녀석입니다. 어떤 녀석이 전체 프로그램에 해당하는 수명을 갖고 있음을 나타내죠. 많은 Rust 프로그래머들은 문자열을 다루면서 `'static`을 처음 마주하게 됩니다.

```rust
let x: &'static str = "Hello, world.";
```

문자열 리터럴은 `&'static str` 타입을 갖고 있는데, 이는 참조가 항상 살아 있는 상태이기 때문입니다. 이 리터럴들은 최종 바이너리의 데이터 영역에 들어가죠. 또 다른 예제는 전역 함수입니다.

```rust
static FOO: i32 = 5;
let x: &'static i32 = &FOO;
```

위의 코드는 `i32`를 바이너리의 데이터 영역에 추가하고, `x`는 그에 대한 참조입니다.

## 수명의 생략(Lifetime Elision)

Rust는 함수 몸체에서는 강력한 로컬 타입 추론을 제공하지만, 아이템 시그니처들에 대해 그 자신에 기반해 그 타입을 추론해내는 것은 금지되어 있습니다. 하지만, 사용자의 편의를 위해 '수명의 생략'이라 불리는, 아주 제한적인 차선의 추론 알고리즘이 함수 시그니처에서의 타입 추론에 적용됩니다. 이 때, 이 추론은 세 개의 쉽게 외울 수 있고 명백한 규칙을 기반으로 *수명 인자들만을* 추론해내며, 함수 몸체와는 무관하게 이루어집니다. 수명의 생략을 통해, 그와 관련된 실제 타입들에 대한 정보를 가리지 않으면서도 아이템 시그니처를 보다 간략하게 작성할 수 있습니다. 마치 로컬 타입 추론처럼요.

수명의 생략에 대해 이야기 할 때, *입력 수명(input lifetime)*과 *출력 수명(output lifetime)*이라는 용어들이 사용됩니다. *입력 수명*이란 함수의 인자와 연관된 수명, *출력 수명*은 함수의 리턴 값과 연관된 수명을 의미합니다. 예를 들어, 다음 함수는 입력 수명을 가지고 있습니다.


```rust,ignore
fn foo<'a>(bar: &'a str)
```

This one has an output lifetime:이 녀석은 출력 수명을 가지고 있구요.

```rust,ignore
fn foo<'a>() -> &'a str
```

This one has a lifetime in both positions:다음에 나올 함수는 두 수명을 모두 갖고 있네요.

```rust,ignore
fn foo<'a>(bar: &'a str) -> &'a str
```

Here are the three rules:

* Each elided lifetime in a function’s arguments becomes a distinct lifetime
parameter.

* If there is exactly one input lifetime, elided or not, that lifetime is
assigned to all elided lifetimes in the return values of that function.

* If there are multiple input lifetimes, but one of them is `&self` or `&mut
self`, the lifetime of `self` is assigned to all elided output lifetimes.

Otherwise, it is an error to elide an output lifetime.

### Examples
앞서 언급한 세 가지 규칙은 다음과 같습니다.

* 함수의 매개변수에서 생략된 수명들은 각각 별개의 수명 인자가 됩니다.

* (생략되었건 아니건) 만약 정확히 한 개의 입력 수명만이 존재한다면, 그 수명이 해당 함수의 리턴 값들의 모든 생략된 수명에 할당됩니다.

* 만약 다수의 입력 수명이 있지만 그 중 하나가 `&self`나 `&mut self`라면, `self`의 수명이 모든 생략된 출력 수명에 할당됩니다.

위의 규칙들로 추론해 낼 수 없는 경우, 출력 수명의 생략은 에러를 발생시킵니다.

### 예제

다음은 생략된 수명을 갖는 함수들의 예제들입니다. 각각의 수명이 생략된 형태의 함수들을 각각 수명이 생략되지 않고 확장된(expanded) 형태와 짝지어 놓았으니, 참고하세요.

Here are some examples of functions with elided lifetimes. We’ve paired each
example of an elided lifetime with its expanded form.

```rust,ignore
fn print(s: &str); // elided
fn print<'a>(s: &'a str); // expanded

fn debug(lvl: u32, s: &str); // elided
fn debug<'a>(lvl: u32, s: &'a str); // expanded

// In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
// reference (`&`). Only things relating to references (such as a `struct`
// which contains a reference) need lifetimes.

fn substr(s: &str, until: u32) -> &str; // elided
fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded

fn get_str() -> &str; // ILLEGAL, no inputs

fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
fn frob<'a, 'b>(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is unclear

fn get_mut(&mut self) -> &mut T; // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded

fn args(&mut self, args: &[T]) -> &mut Command // elided
fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded

fn new(buf: &mut [u8]) -> BufWriter; // elided
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded