Rust1.0学習用私的メモ

2015/5/15に[Rust 1.0が正式リリース](http://blog.rust-lang.org/2015/05/15/Rust-1.0.html)されたので、そこから学習を始めた人間の私的なメモ。

https://play.rust-lang.org/

```rust
// factorial
fn fact(n: i32) -> i32 {
  if n < 2 { 1 } else { n * fact(n-1) }
}
fn main() {
  let n = 5;
  println!("Hello Rust! {}", fact(n));
}
```

[The Rust Project FAQ](http://doc.rust-lang.org/stable/complement-project-faq.html)より：

> What is this project's goal, in one sentence?
> To design and implement a safe, concurrent, practical, static systems language.


# 解説記事
（Rust 1.0以前での言語仕様変更は激しかったらしく、Web上で検索して出てきた記事内容を鵜呑みにしないほうがよさげ。1.0では既に廃止された仕様とかも相当あるみたい。）

rust-lang.orgの[公式ドキュメント](http://doc.rust-lang.org/stable/)が丁寧に書かれている。ここからはじめるべき。

- [Rust by Example](http://rustbyexample.com/)：例示コードで言語機能を概説
- [The Rust Programming Language](http://doc.rust-lang.org/stable/book/)："Learn Rust"は必読
- [The Rust Language FAQ](http://doc.rust-lang.org/stable/complement-lang-faq.html)：Rustの言語機能に関するFAQ
- [The Rust Design FAQ](http://doc.rust-lang.org/stable/complement-lang-faq.html)：プログラミング言語"設計"に関するFAQ
- [The Rust Reference](http://doc.rust-lang.org/stable/reference.html)：（厳密ではない）言語仕様リファレンス

公式ブログ(http://blog.rust-lang.org/)

- [Fearless Concurrency with Rust](http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html)
- [Mixing matching, mutation, and moves in Rust](http://blog.rust-lang.org/2015/04/17/Enums-match-mutation-and-moves.html)
- [Rust Once, Run Everywhere](http://blog.rust-lang.org/2015/04/24/Rust-Once-Run-Everywhere.html)
- [Abstraction without overhead: traits in Rust](http://blog.rust-lang.org/2015/05/11/traits.html)


## ブログ記事
（Rust 1.0対応が確認できたもの）

- [Rust Guidelines [working title]](http://aturon.github.io/)
- [Why your first FizzBuzz implementation may not work](http://chrismorgan.info/blog/rust-fizzbuzz.html)
- [Explore the ownership system in Rust](http://nercury.github.io/rust/guide/2015/01/19/ownership.html)
- [Rust ownership, the hard way](http://chrismorgan.info/blog/rust-ownership-the-hard-way.html)
- [String vs &str in Rust functions](http://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html)
- [Creating a Rust function that accepts String or &str](http://hermanradtke.com/2015/05/06/creating-a-rust-function-that-accepts-string-or-str.html)
- [Creating a Rust function that returns a &str or String](http://hermanradtke.com/2015/05/29/creating-a-rust-function-that-returns-string-or-str.html)
- [Finding Closure in Rust](http://huonw.github.io/blog/2015/05/finding-closure-in-rust/)
- [Error Handling in Rust](http://blog.burntsushi.net/rust-error-handling/)
- [The Problem With Single-threaded Shared Mutability](http://manishearth.github.io/blog/2015/05/17/the-problem-with-shared-mutability/)
- [How Rust Achieves Thread Safety](http://manishearth.github.io/blog/2015/05/30/how-rust-achieves-thread-safety/)
- [Defaulting to Thread-Safety: Closures and Concurrency](http://huonw.github.io/blog/2015/05/defaulting-to-thread-safety/)
- [Some notes on Send and Sync](http://huonw.github.io/blog/2015/02/some-notes-on-send-and-sync/)
- [Peeking inside Trait Objects](http://huonw.github.io/blog/2015/01/peeking-inside-trait-objects/)
- [The Sized Trait](http://huonw.github.io/blog/2015/01/the-sized-trait/)
- [Object Safety](http://huonw.github.io/blog/2015/01/object-safety/)
- [Where Self Meets Sized: Revisiting Object Safety](http://huonw.github.io/blog/2015/05/where-self-meets-sized-revisiting-object-safety/)


## StackOverflow
- [Lifetimes in Rust](http://stackoverflow.com/q/17490716/684921)
- [What are Rust's exact auto-dereferencing rules?](http://stackoverflow.com/q/28519997/684921)
- [How to Iterate Over an Array?](http://stackoverflow.com/q/30467085/684921)
- [How do I create a map from a list in a functional way](http://stackoverflow.com/q/30441698/684921)
- [Rust String versus str](http://stackoverflow.com/q/24158114/684921)
- [Rust: How to create struct with string members?](http://stackoverflow.com/q/25754863/684921)
- [How do I print the type of a variable in Rust?](http://stackoverflow.com/q/21747136/684921)
- [Does println! borrow or own the variable?](http://stackoverflow.com/q/30450399/684921)


# 言語の特徴
http://www.rust-lang.org/

> - ゼロ・コストの抽象化(zero-cost abstractions)
> - ムーブ・セマンティクス(move semantics)
> - メモリ安全性の保証(guaranteed memory safety)
> - データ競合のないスレッド(threads without data races)
> - トレイトに基づくジェネリクス(trait-based generics)
> - パターン・マッチング(pattern matching)
> - 型推論(type inference)
> - 最小のランタイム(minimal runtime)
> - 効率的なCバインディング(efficient C bindings)

https://doc.rust-lang.org/reference.html#behavior-considered-undefined

コンパイル時の型検査によって、次の未定義動作が生じないことを保証する。

> - データ競合(Data races)
> - ヌルポインタや参照先が無効なポインタの参照剥がし(Dereferencing a null/dangling raw pointer)
> - 未定義（未初期化）メモリの読み取り/(Reads of undef (uninitialized) memory)
> - ...

http://doc.rust-lang.org/stable/reference.html#appendix:-influences

他プログラミング言語から影響を受けたRustの言語機能。

> - SML, OCaml: algebraic datatypes, pattern matching, type inference, semicolon statement separation
> - C++: references, RAII, smart pointers, move semantics, monomorphisation, memory model
> - ML Kit, Cyclone: region based memory management
> - Haskell (GHC): typeclasses, type families
> - Newsqueak, Alef, Limbo: channels, concurrency
> - Erlang: message passing, thread failure
> - Swift: optional bindings
> - Scheme: hygienic macros
> - C#: attributes
> - ...


# 構成要素
## 式(expression)と文(statement)
ほとんど全てが **式(expression)** となっている。`if`/`match`/`loop`などのフロー制御やブロック`{`～`}`も式として扱う。

```rust
// 式(expression)
42
()
[1, 2, 3]
0..10
"foobar".to_string()
if 0 < n { n } else { -n }
match opt { Some(_) => true, None => false }
{ println!("Hello"); 42 }
```

文(statement) は 宣言文(declaration statement) と 式文(expression statement) の2種類に大別される。

```rust
// 宣言文
use std::option::Option;
fn f(x: i32) -> i32 { /*...*/ }
struct S { /*...*/ }
enum E { /*...*/ }
const C: i32 = /*...*/
trait T { /*...*/ }
impl T for S { /*...*/ }
```

式文は式(`e`)の末尾に`;`をつけたもの。式文`e;`は常に型unit typeの値`()`となる（値`e`ではない！）。

```rust
fn answer_universe() -> i32 {
  42  // OK: i32型の値42
  // `return 42;`とも書ける

  //42;  // NG: unit typeの値()
  // error: not all control paths return a value [E0269]
}
```


## 基本型(primitive types)とリテラル(literal)

[真偽値型`bool`](http://doc.rust-lang.org/stable/std/primitive.bool.html)は、値`true`／`false`のいずれか。

数値リテラルには型名をサフィックスとして付与する。サフィックス省略時は`i32`または`f64`。整数リテラルはデフォルトで10進数となり、プレフィクス`0b`(2進), `0o`(8進), `0x`(16進)で変更可能。また読みやすさのため、数値リテラル中に区切り文字`_`を含めても良い（任意）。

- 幅指定の整数型：`i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`（2の補数表現）
- 環境依存の整数型：`isize`, `usize`（ポインタ型のビット幅）
- 浮動小数点数型：`f32`, `f64`（IEEE 754 binary32/64準拠）

```rust
0u8      // u8
42isize  // isize
3.14f32  // f32
10_000   // i32
```

> NOTE: Rust1.0以前を対象にした記事では`int`, `uint`が使われていることがある。それぞれ`isize`, `usize`に名称変更されている。[RFC 544](https://github.com/rust-lang/rfcs/blob/master/text/0544-rename-int-uint.md)参照。


[文字型`char`](http://doc.rust-lang.org/stable/std/primitive.char.html)は、有効なUnicode文字を1つ格納する（`u32`と同ビット幅だが有効範囲チェック付き）。文字の配列`[char]`はUCS-4/UTF-32文字列に相当する。文字リテラルはシングルクォーテーション`'`で括る。

[文字列型`str`](http://doc.rust-lang.org/stable/std/primitive.str.html)は、**UTF-8エンコーディングされたバイト列**を表す。文字列リテラルはダブルクォーテーション`"`、または`r#"`～`"#`(raw string)で括る。文字列リテラルは**immutableな文字列**。Rustの文字列リテラルはfirst-class型ではないため、使用時にはポインタ型`&str`として参照する。[^str_literal]

変更可能な文字列として`String`型([std::string::String](http://doc.rust-lang.org/stable/std/string/struct.String.html))が提供されており、文字列リテラル(`str`)からは`to_string()`メソッドで明示的に変換する（複製処理のため少々コスト高）。

```rust
'H'           // char型リテラル H
"Hello"       // str型リテラル Hello
r#""Hello""#  // str型リテラル "Hello"

let s: &str   = "Hello";             // &str型
let s: String = "Hello".to_string()  // String型

let mut s: String = "Hello".to_string();
s.push_str(", World");
// sは値"Hello, World"
```

文字リテラル／文字列リテラルにプレフィクス`b`を付けると、バイト(`u8`)またはバイト配列(`[u8; N]`)リテラルになる。（リテラルが非ASCII文字を含む場合はコンパイルエラー）

```rust
b'H'          // u8型リテラル H
b"Hello"      // &[u8; 5]型リテラル Hello

let bytes = b"漢字";
// error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte: \u{6f22}
// error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte: \u{5b57}

let bytes: &[u8] = b"\x22\x6f\x57\x5b";
let s = String::from_utf8_lossy(bytes);
println!("{}", s);  // "oW[

let chars_u16 : &[u16] = unsafe { std::mem::transmute(bytes) };
let s = String::from_utf16_lossy(chars_u16);
println!("{}", s);  // 漢字
```

文字列処理全般は http://qiita.com/aflc/items/f2be832f9612064b12c6 が参考になった。

[^str_literal]: 文字列リテラルはstatic lifetime、つまりプログラム全域の生存期間(lifetime)を持つ。生存期間を明示する場合は`&'static str`型で参照する。


## タプル(tuple)
任意の型をもつ複数要素をまとめて [タプル(tuple)](http://doc.rust-lang.org/stable/std/primitive.tuple.html) 型を構成する。タプルは各要素をコンマ`,`で区切り、全体を丸括弧`(`～`)`で括る。要素値の設定や読み出しには、後述するパターンマッチを利用するか、`.`の後ろに直接インデクス値を記述する。

```rust
let t: (i32, String) = (10, "ABC".to_string());

let (k0, v0) = t;  // k0は10, v0は"ABC"

let k1 = t.0;  // 10
let v1 = t.1;  // "ABC"

(true)   // bool型
(true,)  // 1要素のタプル型`(bool)`
```

空の値／何も無いことを表すユニット型(unit type)として、値`()`を用いる。文法的には0要素のタプル型（Haskell由来？）。


## 範囲(range)
`..`を用いて整数区間の 範囲(range) を表す。後述するスライスの表現や、`for`式の反復区間指定に用いる。`begin..end`は半開区間[begin,end)を表す。（例：`0..5`は0,1,2,3,4）

```rust
1..2;   // std::ops::Range
3..;    // std::ops::RangeFrom
..4;    // std::ops::RangeTo
..;     // std::ops::RangeFull
```

```rust
// 10回ループ
for i in 0..10 {
  println!("{}", i);
}
```

Range型(`b..e`)とRangeFrom型(`b..`)は`Iterator`トレイト([std::iter::Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html))を実装するため、`rev()`や`collect()`関数などを呼び出せる。

```rust
// 逆順ループ
for i in (1..10).rev() { /*...*/ }

// Vec型に変換
let list : Vec<_> = (0..5).collect();

// 1?10総和を計算
let sum = (1..).take(10).fold(0, |a,n| a+n);
```


## 配列(array)とスライス(slice)
同じ型を持つ複数要素をまとめて [配列(array)](http://doc.rust-lang.org/stable/std/primitive.array.html) 型を構成する。配列型`[T; N]`は要素型`T`と要素数`N`で指定される。いわゆる固定長配列のため、可変長配列が必要ならば`Vec`型([std::vec::Vec](http://doc.rust-lang.org/stable/std/vec/struct.Vec.html))を利用する。配列リテラルは各要素値をコンマ`,`で区切って並べるか、値と要素数を`;`で区切って、全体を角括弧`[`～`]`で括る。

```rust
let a = [1, 2, 3];  // [i32; 3]型の配列[1,2,3]
let b = [0u8; 5];   // [u8; 5]型の配列[0,0,0,0,0]
```

要素数の取得は`len()`メソッドを利用する。要素アクセスには0始まりの添字(indexing)を利用する。配列の範囲外アクセスは、インデクス値がコンパイル時定数ならばコンパイルエラー、そうでなければpanic（実行時エラー）となる。

```rust
let mut x = [1, 2];
x[1] = 100;
// xは配列[1, 100]
let l = x.len();  // 値2
```

配列要素への範囲(range)アクセス方式として、[スライス(slice)](http://doc.rust-lang.org/stable/std/primitive.slice.html) がある。スライスは配列と異なり対象データを所有(own)しないため、ポインタ型`&[T]`として表現される。なお、スライスは配列以外にも`Vec`型に対して適用できる。

```rust
let a: [i32; 4] = [1, 2, 3, 4];  // 配列[1,2,3,4]
let s: &[i32] = &a;        // スライス[1,2,3,4]
let s: &[i32] = &a[2..];   // スライス[3,4]
let s: &[i32] = &a[..2];   // スライス[1,2]
let s: &[i32] = &a[1..3];  // スライス[2,3]

let s: &[i32] = a;  // error: mismatched types: expected `&[i32]`, found `[i32; 4]`

let v = vec!['A', 'B', 'C'];
let s: &[char] = &v;  // スライス['A','B','C']
```


## 構造体(struct)
複数個の型をまとめて新しい 構造体(struct) 型を宣言する。各要素はフィールド(field)と呼ぶ。

```rust
struct Point {
  x: f64,
  y: f64,  // 最後のカンマ(,)はなくても良い
}

let pt = Point { x: 10.0, y: 20.0 };
let x = pt.x;
let Point { x: a, y: b } = pt;  // aに10.0が、bに20.0が代入される
```

フィールド名のないタプル構造体(tuple struct)や、フィールド0個のユニット風構造体(unit-like struct)も定義できる。

```rust
struct Pair(i32, f64);
struct Nil;
```

`..`と組み合わせて、一部フィールドだけを更新した新しい値を簡単に作れる。

```rust
struct Point3D { x: i32, y: i32, z: i32 }

let a = Point3D {x: 1, y: 2, z: 3};
let b = Point3D {y: 10, .. a};  // Point3D{x:1, y:10, z:3}
```


## 変数(variable)
let束縛(let binding)で変数名に値を結びつける。**変数はデフォルトでimmutable**となり、`mut`キーワード指定でmutableな変数となる。

`let` `mut`<sub>opt</sub> <変数名> `=` <値> `;`
または
`let` `mut`<sub>opt</sub> <変数名> `:` <型名> `=` <値> `;`

immutable変数への再代入、およびオブジェクトに対する変更操作が不可能（コンパイルエラー）。mutableとした場合でも、immutable変数で十分な場合はコンパイラが警告してくる。[^unused_mut]

```rust
let x = 3;  // immutable変数
x = 5;  // error: re-assignment of immutable variable `x`

let mut y = 5;  // mutable変数
y = 10;  // OK
```

変数の型は周囲のコンテキストから型推論される。上記コードでは`x`, `y`は整数リテラルのデフォルト型`i32`となる。また下記コードでは`v`は`Vec<f64>`と型推論される（`3.14`は浮動小数点数リテラルのデフォルト型`f64`）。

```rust
let mut v = Vec::new();
v.push(3.14);
```

束縛先には単純な変数名だけでなく、タプルや構造体などによるパターンマッチを利用できる。読み捨てる箇所には`_`を用いる。

```rust
let t = (1, 2, 3);
let (_, y, _) = t;  // OK: yは値2

struct Point { x: f64, y: f64 }
let pt = Point { x: 5.0, y: -8.0 };
let Point { x: a, y: b } = pt;  // OK: aは値5.0, bは値-8.0
```

すでにある変数名(`val`)で再束縛を行うと、前の変数を隠す（再定義エラーとならない）。同じ意味で型だけが異なる場合にいちいち変数名をつけなくて済む。

```rust
let val: Option<i32> = Some(100);
// ...
let val: i32 = v.unwrap_or(42);
```

[^unused_mut]: "warning: variable does not need to be mutable, #[warn(unused_mut)] on by default"


## 関数(function)
`fn`キーワードで 関数(function) を定義する。全ての引数型を明記する必要がある。戻り値型を省略した場合はユニット型`()`となる。引数部分ではlet束縛同様にパターンマッチも使える。

関数の戻り値は、関数本体ブロックにある最後の式の値となる。または`return`式で即時に戻り値を設定して関数を抜ける。

```rust
fn add(x: i32, y: i32) -> i32 {
  x + y
  // `return x + y;`でもOK
}

fn hello(name: String) {
  println!("Hi, {}!", name);
}

fn mid((_, v, _): (i32, i32, i32)) -> i32 { v }
let x = mid((1, 2, 3));  // xは値2
```

また、関数自身の型も`fn`キーワード＋引数型リスト＋戻り値型で記述できる。高階関数の記述などで使う。

```rust
fn mul(x: i32, y: i32) -> i32 { x * y }
let op: fn(i32, i32) -> i32 = mul;  // fn(i32, i32) -> i32型

let x = op(2, 3);  // xは値6 
```


### 関数オーバーロード
Rustでは直接の関数オーバーロードは出来ない。トレイトにより実現する。

```rust
fn dump(x: i32) { println!("i32: {}", x) }
fn dump(x: &str) { println!("str: {}", x) }
// error: duplicate definition of value `dump`
```

```rust
trait DumpVal { fn dump(self); }

impl DumpVal for i32 {
  fn dump(self) { println!("i32: {}", self) }
}
impl DumpVal for &'static str {
  // トレイト実装対象には生存期間'staticの明示的な指定が必要
  // &strだけではコンパイルエラー"error: missing lifetime specifier"
  fn dump(self) { println!("str: {}", self) }
}

DumpVal::dump(42);
DumpVal::dump("hello");
// または
42.dump();
"hello".dump();
```


### main関数
プログラムのエントリポイントは`main()`関数。引数無しかつ戻り値型`()`固定。コマンドライン引数は[`std::env::args()`関数](http://doc.rust-lang.org/std/env/fn.args.html)で取得し、プロセス終了コードは[`std::process::exit()`関数](http://doc.rust-lang.org/std/process/fn.exit.html)で設定できる。

```rust
fn main() {
  for arg in std::env::args() {
    println!("{}", arg);
  }
  std::process::exit(-1);
}
```


## ラムダ式(lambda expression)
ラムダ式(lambda expression)は、バーティカルバー`|`～`|`で囲った引数リスト＋本体式（ブロック式`{`～`}`でもOK）で記述する。ラムダ式は一意なクロージャ(closure)型の値となる。`fn`キーワードによる関数と異なり、**ラムダ式の引数型と戻り値型は型推論される**（明示してもよい）。

```rust
// 引数リスト(i32, i32)をとって戻り値i32を返すクロージャ
let add = |x, y| { x - y };
let sub = |x, y| x + y;
println!("{} {}", add(1,2), sub(1,2));

// 引数なし/戻り値()のクロージャを宣言＆呼出し（意味はない）
(||{})();
```

ラムダ式は環境をキャプチャ(capture their environment)する。キャプチャ操作は、ラムダ式中でアクセスする変数を借用(borrowing)するのと等価。`move`キーワードにより所有権(ownership)を移動するキャプチャ操作に変更できる（`thread::spawn(move || /*...*/);`で利用するパターンが多い）。

```rust
let s = "X".to_string();
{
  let lm = || {  // sを借用
    println!("{}", s)
  };
  println!("{}", s);
  lm();
}
    
{
  let lm = move || {  // sの所有権を移動
    println!("{}", s)
  };
  println!("{}", s);  // error: use of moved value: `s`
  lm();
}
```


### Fn/FnMut/FnOnceトレイト
クロージャや関数は特殊なトレイト`Fn`, `FnMut`, `FnOnce`を自動的に実装する。これらのトレイトは、オブジェクト`f`に対して関数呼び出し形式`f()`で呼び出せる型を表しており、それぞれ第一引数`&self`, `&mut self`, `self`とした関数定義に対応する。（例：`FnOnce`は所有権を移動してしまうため、同オブジェクトに対して1回だけ呼び出せるトレイト）

```rust
// ジェネリクス関数版
fn apply1<F>(f: F, v: i32) where F: Fn(i32) -> i32 {
  // 型Fは引数リスト(&self,i32)をとってi32型を返す呼び出し可能なオブジェクト
  // &selfはキャプチャ環境(変数&m)アクセスのために内部的に用いられる
  println!("{}", f(v));
}

let m = 2;
apply1(|n| n * m, 21);  // クロージャを値渡し（所有権を移動）

fn triple(n: i32) -> i32 { n * 3 }
apply1(triple, 21);  // 関数を値渡し（コピー）
```

```rust
// トレイトオブジェクト版
fn apply2(f: &Fn(i32) -> i32, v: i32) {
  println!("{}", f(v));
}

let m = 2;
apply2(&|n| n * m, 21);  // クロージャを貸出し

fn triple(n: i32) -> i32 { n * 3 }
apply2(&triple, 21);  // 関数を貸出し
```

関数型`fn(i32) -> i32`とトレイト`Fn(i32) -> i32`の混同に注意。関数型にはクロージャを代入できない。


## 実装(implementation)
Rustの構造体は、他のオブジェクト指向言語でいう"クラス"に相当する。`impl`キーワードを用いた 実装(implementation) によってクラスの"メソッド"相当を定義する。

第一引数に`&self`, `&mut self`, `self`のいずれかをとる関数は、インスタンスメソッドに相当する。そうでない関数はクラスメソッドに相当する。`Self`は実装対象の型（構造体）を指す。

```rust
struct S { x: i32, y: i32 }

impl S {
  // インスタンスメソッド（的な関数）
  fn f(&self, a: i32) -> &Self {
    // &selfはいわゆるthisポインタに相当
    println!("{},{}:{}", self.x, self.y, a);
    self  // selfを返すとメソッドチェインをサポート
  }

  // クラスメソッド（的な関数）
  fn h(x: i32) -> () {
    println!("x={}", x);
  }
}

let s = S { x: 1, y: -1 };

s.f(1).f(2);
// S::f(S::f(&s, 1), 2);でもOK

S::h(42);
```

他のオブジェクト指向言語でいう"コンストラクタ"や"デストラクタ"に対応する、直接的なRustの言語要素は存在しない。

- （慣例的に）コンストラクタはメソッド名`new`の関数を定義する。
- デストラクタ相当は`Drop`トレイト([std::ops::Drop](http://doc.rust-lang.org/std/ops/trait.Drop.html))を実装する。

```rust
struct S { x: i32, y: i32 }

impl S {
  // コンストラクタ（相当）
  fn new() -> S {
    // フィールドに初期値を与えた構造体を返す
    S { x: 0, y: 0 }
  }
}

impl Drop for S {
  // デストラクタ（相当）
  fn drop(&mut self) -> () {
    println!("destroyed")
  }
}

{
  let s = S::new();
} // "destroyed"が出力される
```


## トレイト(trait)
`trait`キーワードにより、特定の関数・定数・型を含むといった「型の性質」を記述する トレイト(trait) を宣言する。トレイトは抽象的なインターフェイスであり、構造体などの具象的な型とは異なる。

```rust
trait Shape {
  fn draw(&self, Surface);
  fn bounding_box(&self) -> BoundingBox;
}
```

Rustのトレイトは、他のオブジェクト指向言語でいう"インターフェイス"や"抽象クラス"に似ている一方で、Haskellの"型クラス(type class)"相当の性質もある。継承関係を用いずに型の性質を表現し、オブジェクト多態性や演算子オーバーロードの実装、ジェネリクスでの型制約指定に用いる。

```rust
struct Circle {
  radius: f64,
  center: Point,
}

impl Shape for Circle {
  fn draw(&self, s: Surface) { do_draw_circle(s, *self); }

  fn bounding_box(&self) -> BoundingBox {
    let r = self.radius;
    BoundingBox {
      x: self.center.x - r, y: self.center.y - r,
      width: 2.0 * r, height: 2.0 * r }
  }
}
```

トレイト`T`は具象型ではなく抽象インターフェイスにすぎないため、参照型`&T`や`Box<T>`型のような使い方のみ許容される。直接トレイト`T`型のオブジェクトとして変数を保持することはできない。[^trait_dst]

```rust
struct S;
trait T { fn f(&self); }
impl T for S {
  fn f(&self) { println!("f(&S)") }
}

let x: S = S;
let t: &T = &x;  // OK
t.f();

let b: Box<T> = Box::new(S);  // OK
b.f();

let u: T;
// error: the trait `core::marker::Sized` is not implemented for the type `T`
```

[^trait_dst]: コンパイルエラーは「型`T`が`Sized`トレイトを実装しない」となる。トレイトオブジェクト(trait object)型`T`のサイズがコンパイル時には定まらないという意味。


### ディスパッチ(dispatch)
Rustではトレイトを用いて、ジェネリクス関数によるコンパイル時**静的ディスパッチ(static dispatch)**と、トレイトオブジェクト(trait object)による実行時**動的ディスパッチ(dynamic dispatch)**の2種類をサポートする。

静的ディスパッチでは実行時オーバーヘッドが最小となるが、それぞれの具象型に対してジェネリクス関数が実体化されるため生成コードが肥大化する。動的ディスパッチではコード肥大化を避けられるが、実行時コストは仮想関数呼び出しにより若干のペナルティを受ける。

```rust
trait Animal { fn cry(&self); }

struct Dog;
impl Animal for Dog {
  fn cry(&self) { println!("Bow wow") }
}

struct Cat;
impl Animal for Cat {
  fn cry(&self) { println!("Meow") }
}

// ジェネリクスによる静的ディスパッチ
fn func_static<T: Animal>(pet: &T) {
  // コンパイル時に決定するT型により呼び出し関数を決定
  pet.cry()
}

// トレイトオブジェクトによる動的ディスパッチ
fn func_dynamic(pet: &Animal) {
  // Animalトレイトオブジェクトを経由して実行時に呼び出し関数を決定
  pet.cry()
}

let (dog, cat) = (Dog, Cat);

// ジェネリクスによる静的ディスパッチ
func_static(&dog);
func_static(&cat);

// トレイトオブジェクトによる動的ディスパッチ
func_dynamic(&dog);
func_dynamic(&cat);
```


### マーカ・トレイト
一部トレイトは型の性質を示すだけのマーカーであり（中身のないトレイト）、型に関する振る舞いの指定や、コンパイル時の型検査に利用される。

- [Copyトレイト](http://doc.rust-lang.org/std/marker/trait.Copy.html)：バイトコピー(memcpy)で複製可能。Copyトレイトを実装する型はコピー・セマンティクスを持つ。
- [Sizedトレイト](http://doc.rust-lang.org/std/marker/trait.Sized.html)：コンパイル時に型サイズが確定する。
- [Sendトレイト](http://doc.rust-lang.org/std/marker/trait.Send.html)：スレッド境界をまたいで転送できる。
- [Syncトレイト](http://doc.rust-lang.org/std/marker/trait.Sync.html)：スレッド境界をまたいで共有できる。いわゆる同期化された型。


### derive属性
`derive`属性(attribute)を用いると、構造体に対してトレイトを自動的に実装できる（可能ならば）。下記例では構造体`S`に`Copy`, `Clone`両トレイトを実装している。[^copy_trait]

```rust
#[derive(Copy, Clone)]
struct S;

// 下記宣言に相当する
struct S;
impl Copy for S {}
impl Clone for S { fn clone(&self) -> S { *self } }
```

[^copy_trait]: CopyトレイトはCloneトレイトを継承しているため、Copyトレイト実装にはCloneトレイトの実装が必須。逆に、Cloneトレイトのみ実装は可能（`clone()`関数によって明示的に複製可能だが、基本はムーブセマンティクスの型となる）。


## 列挙型(enumeration)
とりうる値を列挙した 列挙型(enumeration) を宣言する。

```rust
enum Animal {
  Dog,
  Cat
}

let a: Animal = Animal::Dog;
```

Rustの列挙型は単純な値列挙だけではなく、代数的データ型(algebraic data type)／タグ付き共用体(tagged union)となっており、それぞれの列挙値がさらにデータを保持できる。

```rust
enum List<T> {
  Nil,                   // List終端マーカ
  Cons(T, Box<List<T>>)  // Consセル: 値と次セルへのポインタ
}

impl<T> List<T> {
  // リスト長を返す
  fn len(&self) -> usize {
    match *self {
      List::Nil => 0,
      List::Cons(_, ref cdr) => 1 + cdr.len()
    }
  }
}

let a: List<i32> = List::Cons(7, Box::new(List::Cons(13, Box::new(List::Nil))));
let l = a.len();  // lは値2
```

Rust標準ライブラリでは、`Option`型と`Result`型を全面的に利用している。値を取りだすときは`match`式でパターンマッチを行うか、`unwrap()`関数を呼び出す（None/Errの場合はpanic）。

- [Option型](http://doc.rust-lang.org/std/option/enum.Option.html)：有効値(`Some<T>`)または無効値(`None`)を表す。
- [Result型](http://doc.rust-lang.org/std/result/enum.Result.html)：関数戻り値として、成功(`Ok(T)`)または失敗(`Err(E)`)を表す。


## ジェネリクス(generics)
関数(`fn`)／構造体(`sturct`)／列挙体(`eunm`)／トレイト(`trait`)において、ジェネリクス(generics) により型情報をパラメータ化できる。型パラメータに関する制約(bound)は、`where`キーワードとトレイトを用いて記述する。

```rust
use std::fmt::Debug;
fn dump<T>(v: T) where T: Debug {
  // "{:?}"書式にはDebugトレイトが実装されている必要あり
  println!("{:?}", v)
}
dump(1);
dump("hello");

// 制約は型パラメータTの直後に書いてもよい
fn dump<T: Debug>(v: T) { /*...*/ }
```

```rust
struct Pair<T> {
  first: T,
  second: T,
}

fn swap<T>(pair: Pair<T>) -> Pair<T> {
  let Pair { f, s } = pair;
  Pair { first: s, second: f }
}
```

型パラメータの制約では`+`により複数トレイトの指定や（例：`T: Eq + Ord`）、`!`による否定制約の指定（例：`T: !Send`）、生存期間(lifetime)を指定することもできる（例：`F: Send + 'static`）。また、型パラメータ`T`では暗黙に`Sized`マーカ・トレイトを要求するため、動的サイズ型(DST; dynamically sized type)も許容するには`T: ?Sized`制約を指定する。[^dst_bound]

[^dst_bound]: スライス型`[T]`はdynamically sized type。


## マクロ(macro)
任意の マクロ(macro) をユーザ定義／利用できる。マクロ名の末尾文字は必ずエクスクラメーション`!`とする（例：`println!`, `panic!`）。Rustのマクロは、C/C++言語マクロのようなトークン置換ではなく、Scheme言語のような[Hygienic Macro](http://en.wikipedia.org/wiki/Hygienic_macro)（直訳すると"健全なマクロ"）となっている。

標準ライブラリで提供される代表的なマクロ：

- [format!](https://doc.rust-lang.org/std/macro.format!.html)：書式指定にしたがった文字列化／`String`を返す
- [vec!](https://doc.rust-lang.org/std/macro.vec!.html)：可変長配列オブジェクトを生成／`Vec`を返す
- [println!](https://doc.rust-lang.org/std/macro.println!.html)：標準出力に文字列出力（改行付き）
- [concat!](https://doc.rust-lang.org/std/macro.concat!.html)：複数リテラルを連結して文字列リテラル化
- [print!](https://doc.rust-lang.org/std/macro.print!.html)：標準出力に文字列出力（改行なし）
- [try!](https://doc.rust-lang.org/std/macro.try!.html)：`Result`型を返す関数での`Err`処理補助ラッパー
- [panic!](https://doc.rust-lang.org/std/macro.panic!.html)：スレッドを異常停止
- [assert!](https://doc.rust-lang.org/std/macro.assert!.html)：実行時アサーション


# 動作モデル
## 所有権(ownership)
Rustのオブジェクトはただ1つの変数によって 所有権(ownership) を管理される。所有権が手放されたタイミングで、オブジェクトは破棄されメモリも回収される。（Rustには非決定動作のGC機構は存在しない。）

ある変数を別の変数に束縛した場合、オブジェクトの**所有権が移動**する（デフォルトでムーブ・セマンティクス）。所有権の移動は**コンパイル時に追跡され**ており、所有権を持たない変数にアクセスするとコンパイルエラーとして検知する。

```rust
let a: String = "ABC".to_string();  // 変数aがオブジェクト"ABC"を所有
let b: String = a;  // 変数bにオブジェクトの所有権を移動

println!("b={}", b);  // OK
println!("a={}", a);  // NG: 既に変数aは所有権をもっていない
// error: use of moved value: `a`
```

オブジェクトをコピーするには、`Clone`トレイト([std::clone::Clone](http://doc.rust-lang.org/std/clone/trait.Clone.html))の`clone()`関数を明示的に呼び出す。

```rust
let a: String = "ABC".to_string();
let b: String = a.clone();  // オブジェクトを複製して変数bに束縛

println!("a={}, b={}", a, b);  // OK
```

`i32`, `f64`などプリミティブ型のように"値のセマンティクス"を持つ型では、**`Copy`トレイトを実装するとコピー・セマンティクスに変更**される([std::marker::Copy](http://doc.rust-lang.org/std/marker/trait.Copy.html))。`Copy`トレイトはコンパイラに対する型の動作指定として機能する。

```rust
let a: i32 = 42;  // 変数aがオブジェクト42を所有
let b: i32 = a;  // 変数bにオブジェクト42を複製して束縛

println!("a={}, b={}", a, b);  // OK
```

独自定義の型でも`Copy`トレイトと`Clone`トレイトを実装しておくことで、コピー・セマンティクスに変更できる。（`Debug`トレイトは書式`{:?}`対応に必要。）

```rust
#[derive(Copy,Clone,Debug)]
struct Point (i32, i32);

let a: Point = Point (0, 1);
let b: Point = a;  // コピー・セマンティクス
println!("a={:?}, b={:?}", a, b);  // OK
```


## 借用(borrowing)
Rustの参照(reference)型変数では、参照元の変数が所有するオブジェクトの所有権を、参照変数の有効期間の間だけ **借用(borrowing)** する。ある変数の参照を得る（所有権を借りる）には、`&`または`&mut`単項演算子を用いる。

所有権の貸出元である変数には、その**貸出期間中にオブジェクトの所有権を手放す操作が許可されない**（ダングリング参照をつくらせない）。また`&mut`演算子による**mutableな参照は同時に1つだけしか貸出しできない**ことに注意。借用による所有権の一時移動もコンパイル時に追跡されている。

```rust
let mut a: String = "abc".to_string();
{
  // aの変更可能な参照(&mut String)をbに束縛
  let b: &mut String = &mut a;
  b.push_str("xyz");
  println!("b={}", b);  // OK: bは値"abcxyz"

  // aは所有権を貸出し中のため所有権を手放せない
  let x: String = a;
  // error: cannot move out of `a` because it is borrowed

  // aは所有権を貸出し中のため所有権を手放せない
  a = "other".to_string();
  // error: cannot assign to `a` because it is borrowed

  // aはmutable参照を貸出し中のため2度目以降の貸出し不可
  let c: &mut String = &mut a;
  // error: cannot borrow `a` as mutable more than once at a time

} // bが借用していた所有権をaに返す
println!("a={}", a);  // OK: aは値"abcxyz"

{
  let b: &mut String = &mut a;  // aのmutalbe参照をbに束縛
  let c: &mut String = b;       // bが借用中の所有権をcに又貸し

  // この時点でbは所有権を借用していない
  b.push_str("Nope");
  // error: cannot borrow `*b` as mutable more than once at a time
}

{
  // immutable参照ならばいくらでも借用できる
  let b: &String = &a;
  println!("a={}, b={}", a, b);  // OK
  let c: &String = &a;
  println!("a={},　b={}, c={}", a, b, c);  // OK
}
```


##自動デリファレンス
オブジェクトに対する関数呼び出しでは、自動デリファレンス(auto dereference) という仕組みにより関数探索が行われる。デリファレンス演算子`*`は`Deref`トレイト([std::ops::Deref](https://doc.rust-lang.org/std/ops/trait.Deref.html)), `DerefMut`トレイト([std::ops::DerefMut](https://doc.rust-lang.org/std/ops/trait.DerefMut.html))により演算子オーバーロードできるが、関数呼び出し時には対象関数名がみつかるまでコンパイラによって再帰的にデリファレンス演算子`*`が適用される。

例えば`Vec<T>`型オブジェクト`v`は`iter()`関数を直接実装しないが、`deref()`によりスライス型`&[T]`に自動変換され、[スライスの`iter`関数](http://doc.rust-lang.org/std/primitive.slice.html#method.iter)が呼び出される。参照型`&Vec<T>`や`Box<T>`, `Rc<T>`などの場合は2回デリファレンスが行われる。

```rust
let v: Vec<i32> = vec![1, 2, 3];
for e in v.iter() { ... }
for e in (*v).iter() { ... }

let r: &Vec<i32> = &v;
for e in r.iter() { ... }
for e in (*r).iter() { ... }
for e in (**r).iter() { ... }

use std::boxed::Box;
let bv = Box::new(vec![1, 2, 3]);
for e in bv.iter() { ... }

use std::rc::Rc;
let rcv = Rc::new(vec![1, 2, 3]);
for e in rcv.iter() { ... }
```

この動作を理解していないとAPIリファレンスをまともに読めない。http://qiita.com/wada314/items/8b63d66b26abaacab456 でも触れられているが、2015年6月現在の[APIリファレンス](http://doc.rust-lang.org/std/)では自動デリファレンス先も含めて表示されるよう改善されている。


## 生存期間(lifetime)
全てのオブジェクトは 生存期間(lifetime) をもっており、Rustではこの**生存期間も型情報の一部**として扱う。生存期間はオブジェクト生成地点から、所有権を持つ変数が属するブロックスコープ(`{`～`}`)終端までで定義され、生存期間に関する不整合はコンパイル時にチェックされる。例えばオブジェクト生存期間(`val`)より広い生存期間の参照変数(`r`)では、そのオブジェクトを借用(`r = &val`)できない。

```rust
{
  let mut r: &String;
  {
    let val: String = "X".to_string();
    r = &val;  // error: `val` does not live long enough
  } // valが所有権を持つ値"X"の生存期間はここまで

  // rが参照&valを保持するべきでない区間！

} // 変数rの生存期間はここまで

let outer_val: String;
{
  let mut r: &String;
  {
    let val: String = "OK".to_string();
    outer_val = val;  // 所有権をouter_valに移動
    r = &outer_val;
  } // valは何の所有権も持っていない

  println!("{}", r);  // OK

} // outer_valが所有権を持つ値"OK"の生存期間ここまで
```

プログラム全域の生存期間を表す`'static`を除いて、生存期間を直接表す名前は存在しない。ジェネリクス関数や構造体の定義では、アポストロフィー`'`＋生存期間パラメータ名で扱う（慣例的に`'a`, `'b`...を用いる）。

```rust
// 参照先の生存期間を暗黙にとる関数
fn foo(x: &i32) { /*...*/ }

// 参照先の生存期間を明示的にとる関数（ジェネリクス）
fn bar<'a>(x: &'a i32) { /*...*/ }

// 戻り値の参照は、関数引数の参照と同じ生存期間を持つ
fn max<'a>(x: &'a Foo, y: &'a Foo) -> &'a Foo {
  if x.f > y.f { x } else { y }
}

// 生存期間を明示した参照をフィールドに持つ構造体
struct RefS<'a> { x: &'a i32 }

// 文字列リテラルは'static生存期間を持つ
let s: &'static str = "literal";
```


## ヒープとBox型
Rustのオブジェクトは、デフォルトではスタック上に確保される。ヒープ上に動的メモリ確保＆管理を行うには`Box`型([std::boxed::Box](https://doc.rust-lang.org/std/boxed/struct.Box.html))を利用する。Rustの`Box<T>`はC++の`unique_ptr<T>`の動作が近い。`Box<T>`型オブジェクトを複製(`clone()`)する場合、ヒープ上の`T`型オブジェクトごと複製される（オブジェクトは共有されない）。`Box<T>`型オブジェクトの生存期間が終わるときにヒープメモリが自動解放される。

```rust
#[derive(Debug)]
struct Person { id: u32, name: String, age: i8 }

impl Person {
  fn new(id: u32, name: &'static str, age: i8) -> Person {
    Person { id: id, name: name.to_string(), age: age }
  }
}

let stack : Person = Person::new(1, "foo", 17);
let heap : Box<Person> = Box::new(Person::new(2, "bar", 34));
println!("{:?} {:?}", stack, heap);

// Person型がCloneトレイトを実装しないため、Box<Person>も複製不可
let a = heap.clone();
// error: type `Box<Person>` does not implement any method in scope named `clone`
```

> NOTE: 一部の記事では、`Box::new()`関数ではなく`box`キーワードを利用しているものがある。Rust 1.0 Stable Channelでは`box`キーワードはまだunstableのため利用不可。
> NOTE: Rust1.0以前を対象にした記事では、チルダ`~`を型修飾子のように利用しているものがある。型`T`に対する`~T`は概ね`Box<T>`と読み替えればよい。[RFC 59](https://github.com/rust-lang/rfcs/blob/master/text/0059-remove-tilde.md)参照。


## Rc型
複数の変数からヒープ上の**immutableオブジェクトを共有**する仕組みとして、参照カウント(reference count)方式による`Rc`型([std::rc::Rc](https://doc.rust-lang.org/std/rc/struct.Rc.html))が提供される。Rustの`Rc<T>`はC++の`shared_ptr<T>`の動作が近い。`Rc<T>`型オブジェクトを複製(`clone()`)すると、参照カウンタを増やして`T`型オブジェクトを共有する。`Rc<T>`型オブジェクトの生存期間が終わり、参照カウントがゼロになったときにヒープメモリが自動解放される。

```rust
#[derive(Debug)]
struct Person { id: u32, name: String, age: i8 }

impl Person {
  fn new(id: u32, name: &'static str, age: i8) -> Person {
    Person { id: id, name: name.to_string(), age: age }
  }
}

let mut a = Rc::new(Person::new(2, "bar", 34));
let mut b = a.clone();
// a,bから参照するため参照カウンタは2
```

`Rc<T>`型はmutableなオブジェクトを直接共有できない。変更可能なフィールドは後述する`RefCell`型または`Cell`型で保持する必要がある。

`Rc`型はスレッド境界をまたぐことが出来ない（コンパイルエラーになる）。複数スレッド間でオブジェクトを共有するには後述する`Arc`型を用いる。

```rust
let a = Rc::new(100);

std::thread::spawn(move || {
// error: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<i32>` [E0277]
  println!("{}", a);
});
```

> NOTE: Rust1.0以前を対象にした記事では、アットマーク`@`を型修飾子のように利用しているものがある。型`T`に対する`@T`は概ね`Rc<T>`と読み替えればよい（既にセマンティクスも異なるが大雑把な対応付けとして）。[RFC 256](https://github.com/rust-lang/rfcs/blob/master/text/0256-remove-refcounting-gc-of-t.md)参照。


## RefCell/Cell型
immutableなオブジェクトの一部としてmutableなサブオブジェクトを保持する仕組み(interior mutability)として、`RefCell`型([std::cell::RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html))および`Cell`型([std::cell::Cell](https://doc.rust-lang.org/std/cell/struct.Cell.html))が提供される。`RefCell`は通常の型に、`Cell`はコピー・セマンティクスの型に対して使用する。

```rust
use std::cell::RefCell;

#[derive(Debug)]
struct Bar { v: i32 }
struct Foo {
  bar: RefCell<Bar>
}

impl Foo {
  fn new(v: i32) -> Foo {
    Foo { bar: RefCell::new(Bar{ v: v }) }
  }
}

// fooはimmutable変数／foo.barオブジェクトもimmutable
let foo: Foo = Foo::new(0);
{
  // RefCell<Bar>内部Bar型オブジェクトのmutable参照を取得
  let mut b = foo.bar.borrow_mut();
  b.v = 42;
}
println!("{:?}", foo.bar.borrow());  // Bar { v: 42 }
```

`RefCell`型の中身にアクセスするため`borrow()`／`borrow_mut()`関数が提供されるが、既にmutable参照を借用中／他の参照を借用中の場合はpanicを引き起こすことに注意（コンパイル時borrow checkerの検査対象外）。


## Cow型
Clone-on-Writeスマートポインタとして`Cow`型([std::borrrow::Cow](https://doc.rust-lang.org/std/borrow/enum.Cow.html))が提供される。mutable(Write)操作または所有権を必要とするまでは、immutableな単一オブジェクトを共有できる。

`Cow<'static, str>`型は、immutalbe文字列リテラル`'static str`とmutable文字列`String`を効率的に取り扱うのにも利用できる。

```rust
use std::borrow::Cow;

fn fizz_buzz(i: i32) -> Cow<'static, str> {
  if i % 15 == 0 {
    "FizzBuzz".into()
    // Cow::Borrowed("FizzBuzz")でもOK
  } else if i % 5 == 0 {
    "Buzz".into()
  } else if i % 3 == 0 {
    "Fizz".into()
  } else {
    i.to_string().into()
    // Cow::Owned(i.to_string())でもOK
  }
}

for i in 1..21 {
  print!("{} ", fizz_buzz(i));
}
```

上記コードでは、`Into`トレイト([std::convert::Into](https://doc.rust-lang.org/std/convert/trait.Into.html))の`into()`関数を利用して適切な`Cow::Borrowed`/`Cow::Owned`に自動変換している。[^into_trait]

[^into_trait]: `Into`トレイト実装では`From`トレイト([std::convert::From](https://doc.rust-lang.org/std/convert/trait.From.html))に転送し、`impl From<&'a str> for Cow<'a, str>`または`impl From<String> for Cow<'a, str>`から適切な関数が自動選択されている。ような気がする。ドキュメンテーションの圧倒的な不足感。


## Arc型とSyncトレイト
異なるスレッド間でimmutableオブジェクトを共有する仕組みとして、アトミックな参照カウント(atomically reference count)方式による`Arc`型([std::sync::Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html))が提供される。`Arc`型はスレッド間共有を許可する`Rc`型といえる。

```rust
use std::sync::Arc;

let shared_v: Arc<Vec<i32>> = Arc::new(vec![1, 2, 3, 4]);
for i in 0..4 {
  // 新スレッド用にArc参照カウント+1
  let thread_vec: Arc<Vec<i32>> = shared_v.clone();

  // 変数thread_viewをムーブキャプチャ
  thread::spawn(move || {
    // thread_vecから読み取り操作
    println!("{}", thread_vec[i]);
  });
}
```

スレッド境界を越えてオブジェクトを安全に共有するには、`Sync`トレイト([std::marker::Sync](https://doc.rust-lang.org/std/marker/trait.Sync.html))が実装されている必要がある。mutableサブオブジェクトを格納する`RefCell`/`Cell`型は同トレイトを実装しないため、スレッド境界をまたいで共有することが出来ない（データ競合可能性をコンパイル時に検査）。[^unsafecell]

```rust
use std::cell::Cell;
use std::sync::Arc;

let shared_v: Arc<Cell<i32>> = Arc::new(Cell::new(42));
for i in 0..3 {
  let thread_view: Arc<Cell<i32>> = shared_v.clone();

  std::thread::spawn(move || {
  // error: the trait `core::marker::Sync` is not implemented for the type `core::cell::UnsafeCell<i32>` [E0277]
    thread_view.set(i);
  });
}
```

スレッド間でmutableオブジェクトを共有するには、後述する`Mutex`型や`RwLock`型を利用する必要がある。

[^unsafecell]: rustcコンパイラのエラーメッセージは「`UnsafeCell`型が`Sync`トレイト未実装」となる。これは`RefCell`, `Cell`が`UnsafeCell`型フィールドを内包し、かつ`UnsafeCell<T>`が`Sync`トレイトを明示的に実装しないよう宣言されているため。エラーメッセージが不親切な気がする。


## Mutex/RwLock型
異なるスレッド間でmutableなオブジェクトを共有するには、排他制御`Mutex`型([std::sync::Mutex](https://doc.rust-lang.org/std/sync/struct.Mutex.html))またはReader-Writerロック制御`RwLock`型([std::sync::RwLock](https://doc.rust-lang.org/std/sync/struct.RwLock.html))を用いる。これらの型は**保護対象オブジェクトを内包し、アクセス時にはロック獲得が必須**となっている。また各スレッドで排他制御オブジェクトを共有するには、`Arc`型と組み合わせる必要がある（常に`Arc<Mutex<T>>`, `Arc<RwLock<T>>`の形で利用する）。

```rust
use std::sync::{Arc, Mutex};

let shared_v: Arc<Mutex<i32>> = Arc::new(Mutex::new(42));
for i in 0..3 {
  // 新スレッド用にArc参照カウント+1
  let thread_view: Arc<Mutex<i32>> = shared_v.clone();

  // 変数thread_viewをムーブキャプチャ
  std::thread::spawn(move || {
    // thread_vecの排他ロックを獲得
    let mut obj: &mut i32 = thread_view.lock().unwrap();

    *obj = i;

    // objの所有権放棄＝ロック解放
  });
}
```


## チャネル
メッセージ・パッシング方式のスレッド間通信をサポートするため、Multi-Producer/Single-Consumer FIFOキュー([std::sync::mpscモジュール](https://doc.rust-lang.org/std/sync/mpsc/index.html))によるチャネル機構が提供される。非同期送信チャネル`channel()`と、上限付き同期送信チャネル`sync_channel()`の2種類がある。受信側は非ブロッキング動作`try_recv()`とブロッキング動作`recv()`をサポートする。

```rust
use std::thread;
use std::sync::mpsc::channel;

let (tx, rx) = channel();
for i in 0..10 {
  let tx = tx.clone();
  thread::spawn(move|| {
    // データ送信（10スレッド並行）
    tx.send(i).unwrap();
  });
}

for _ in 0..10 {
  // データ受信
  let j = rx.recv().unwrap();
  assert!(0 <= j && j < 10);
}
```

> NOTE: 複数チャネルからの選択的受信処理（Go言語のselect/case構文に相当）には、`Select`型([std::sync::mpsc::Select](https://doc.rust-lang.org/std/sync/mpsc/struct.Select.html))と[`select!`マクロ](https://doc.rust-lang.org/std/macro.select!.html)が提供される。Rust 1.0 Stable Channelではまだunstableのため利用不可。手軽に使えないとメッセージ・パッシング方式の実用は厳しい…

----