[RustDoc翻訳] 5.7. Ownership

暫く放置していたのですがモチベが湧いたので再開します。
今の所、所有権借用生存期から並列処理周りの翻訳を行っていきたいと考えています。
前: [5.23. Trait Objects](http://qiita.com/_Nnwww/items/0f9c949bcfd6133dda6e) 次: [5.8. References and Borrowing](http://qiita.com/_Nnwww/items/9ae37aa965323672b91c)
誤訳や改善案等、見つけた場合はご指摘の程宜しくお願いします。

* 元記事 : https://doc.rust-lang.org/book/ownership.html のRust1.5時点
* ライセンス : MIT license, Apache License 2.0.
    - See [LICENSE-APACHE](https://github.com/rust-lang/rust/blob/1.5.0/LICENSE-APACHE), [LICENSE-MIT](https://github.com/rust-lang/rust/blob/1.5.0/LICENSE-MIT), and [COPYRIGHT](https://github.com/rust-lang/rust/blob/1.5.0/COPYRIGHT) for details.

---

# 所有権

このガイドはRustの所有権システムに含まれる3要素の内の1つについて示したものです。これはRustの開発者が熟達すべきであり、かつRustの最もユニークで魅力的な機能の1つです。所有権はRustの最大の目的であるメモリ安全性を実現する方法です。以下の章でそれぞれ別個の概念について説明しています。

* 今あなたが読んでいるのが所有権です
* '参照'の機能に関係するのが[借用][borrowing]です
* 借用を進めた概念が[生存期][lifetimes]です

これら3つの章はその順序にも関係があります。所有権システムの完全な理解のためには3つ全ての読解が必要となるでしょう。

[borrowing]: https://doc.rust-lang.org/book/references-and-borrowing.html
[lifetimes]: https://doc.rust-lang.org/book/lifetimes.html

# メタ[^meta]

詳細について見て行く前に、所有権システムについて2つ重要な注意事項があります。

Rustは安全性と速度に焦点を当てています。それら目的は、Rustにおいて動作のための抽象化コストを可能な限り抑えることを意味する'ゼロコストの抽象化'を多く行うことで達成しています。所有権システムはゼロコストの抽象化の典型的な例です。私たちがこのガイドで話す詳細の全ては_コンパイル時に行われます_。あなたはこれらの機能のために実行時コストを払うことはありません。

しかしながら、このシステムは確実にコストを要し、その影響は学習曲線に現れます。多くのRustの新規ユーザは自身が有効だと考えているプログラムのコンパイルをコンパイラに拒否されるという、所謂'ボローチェッカーとの戦い'を経験しています。これがしばしば起きるのはプログラマが頭の中で考える所有権がこのように動作するはずだというモデルとRustに実装された実際のルールが一致しないためです。あなたも恐らく初めは同じようなことを経験するでしょう。しかしながら良い知らせもあります。経験豊富なRustの開発者曰く、一度でもある程度の期間所有権システムのルールの下で作業すれば、借用チェッカーとの戦いは次第に減っていくとのことです。

このことを念頭において、所有権について学んでいきましょう。

# 所有権

[変数束縛][bindings]はRustにおいて所有権を持つ方法です。束縛している対象の'所有権を持っている'のです。これは束縛している変数がスコープ外に出ると、束縛されていたリソースが開放されることを意味しています。例えば、

```rust
fn foo() {
    let v = vec![1, 2, 3];
}
```

`v`がスコープに入ってくると、新たな[`Vec<T>`][vect]が作成されます。このケースでは、vectorは3つの要素のために[ヒープ領域][heap]の空間をアロケートします。`foo()`が終了し`v`がスコープの外へ出ると、Rustはヒープ領域にアロケートされたメモリも含めvectorに関連する全てを片付けます。これはスコープの終端に達したとき、確定的に行われます。

[vect]: https://doc.rust-lang.org/std/vec/struct.Vec.html
[heap]: https://doc.rust-lang.org/book/the-stack-and-the-heap.html
[bindings]: https://doc.rust-lang.org/book/variable-bindings.html

# ムーブセマンティクス

少し細かい話になりますが、Rustはあらゆるリソースについて束縛が_厳密に1つ_だけあることを保証します。例えばvectorを作成したとして、もう1つ束縛をアサインできます。

```rust
let v = vec![1, 2, 3];

let v2 = v;
```

しかし、その後`v`を使おうとすると、エラーが発生します。

```rust,ignore
let v = vec![1, 2, 3];

let v2 = v;

println!("v[0] is: {}", v[0]);
```

エラーの内容は次のようになります。

```text
error: use of moved value: `v`
println!("v[0] is: {}", v[0]);
                        ^
```

私たちが所有権を受け取る関数を定義し、引数として渡した後に変数を使おうとする場合にも同じようなことが起きます。

```rust,ignore
fn take(v: Vec<i32>) {
    // ここで起きることは重要ではありません。
}

let v = vec![1, 2, 3];

take(v);

println!("v[0] is: {}", v[0]);
```

'use of moved value'、同じエラーですね。何か他の対象へ所有権を譲渡するとき、私たちはその値を'ムーブ'したと言います。このとき特別なアノテーションの類は必要なく、Rustの動作はこれがデフォルトです。

## 詳細

ムーブした後の値を使うことができない理由は細かいようですが重要な話です。このようなコードを書いているとき、

```rust
let v = vec![1, 2, 3];

let v2 = v;
```

1行目はvectorオブジェクト`v`と格納しているデータのためにメモリをアロケートしています。vectorオブジェクトは[スタック領域][sh]に保存されており、[ヒープ領域][sh]に保存されている要素(`[1, 2, 3]`)へのポインタを格納しています。`v`を`v2`へムーブすると、`v2`のためにポインタのコピーを作成します。するとヒープ領域上のvectorの要素を指すポインタが2つになってしまい、データの競合が引き起こされ、Rustの安全性の保証を違反することになります。従って、Rustはムーブした後の`v`の使用を禁じているのです。

[sh]: https://doc.rust-lang.org/book/the-stack-and-the-heap.html

また、状況に応じて、最適化がスタック領域上のデータのコピーを取り除く可能性に気を払うことも大切です。ですから最初に思ったほど非効率的ではないかもしれません。

## `Copy` 型

所有権が他の束縛に移譲されると元の束縛が使用できなくなる所までは話してきました。しかしながら、その振る舞いを変える[トレイト][traits]があり、それは`Copy`と呼ばれています。私たちはまだトレイトについて議論することができませんから、今だけ振る舞いを追加する特殊な型のためのアノテーションと考えてください。例えば、

```rust
let v = 1;

let v2 = v;

println!("v is: {}", v);
```

このケースでは、`v`は`Copy`トレイトを実装する`i32`です。これはムーブと同じく`v`を`v2`へアサインする際に、データのコピーが生成されるという意味です。ただし、ムーブと異なり、その後も`v`を使うことができます。何故なら`i32`はどんなポインタも含んでおらず、「データのコピー」とは値自体を丸ごとコピーすることだからです。

全てのプリミティブ型はCopyトレイトを実装しているため、それらの所有権は'所有権のルール'に則ったムーブが行われません。例を挙げるなら`i32`と`bool`型が`Copy`トレイトを実装していますから、以下の2つのスニペットをコンパイルしてみます。

```rust
fn main() {
    let a = 5;

    let _y = double(a);
    println!("{}", a);
}

fn double(x: i32) -> i32 {
    x * 2
}
```

```rust
fn main() {
    let a = true;

    let _y = change_truth(a);
    println!("{}", a);
}

fn change_truth(x: bool) -> bool {
    !x
}
```

もしこれが`Copy`トレイトを実装していない型だったとすると、ムーブされた値を使おうとすることになりますからコンパイルエラーになるでしょう。

```rust
error: use of moved value: `a`
println!("{}", a);
               ^
```

あなた自身が作った型を`Copy`する方法については[トレイト][traits]の章で論じています。

[traits]: http://qiita.com/_Nnwww/items/892e0d765b7c2a97661e

# 所有権よりも

勿論、元々持っていた所有権を関数に返して欲しければこう書くでしょう。

```rust
fn foo(v: Vec<i32>) -> Vec<i32> {
    // vで何かする

    // 所有権を返す
    v
}
```

これだと非常にうんざりすることになるはずです。受け取りたい所有権が多くなる程悪化してしまいます。

```rust
fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
    // v1とv2で何かする

    // 返して欲しい所有権と関数の結果
    (v1, v2, 42)
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let (v1, v2, answer) = foo(v1, v2);
```

うわっ！返り値の型と返り値を書く行、そして関数の呼び出しが更に複雑になってしまいました。

幸いにも、Rustはこの問題を解決するのに役立つ、借用という機能を提供しています。それが次の章の話題です！

---

#### 訳注

[^meta]: 所有権システム3要素の全ページに記載されている話です。内容は変わりません。