[Rust] チュートリアル⑥　高度な型〜高度な関数とクロージャまで

# はじめに
Rustのチュートリアルのメモです⑥。


# リンク集

[C++入門](https://amzn.to/2Nf1ntW)
[プログラミングRust (日本語) ](https://amzn.to/2Bs7vvS)
[プログラミング言語Rust入門](https://amzn.to/2BkGP0n)
[実践Rust入門](https://amzn.to/2zRbu4W)

[std::検索](https://doc.rust-lang.org/stable/std/)


# 高度な機能

- Unsafe Rust
  - Rustの保証の一部を抜けてその保証を手動で保持する責任を負う方法
- 高度なライフタイム
  - 複雑なライフタイム状況の記述

- 高度な型
  - ニュータイプパターンについてもっと、型エイリアス、never型, 動的サイズ型

- 高度な関数とクロージャ
  - 関数ポインタとクロージャの返却


## Unsafe Rust

Rustのメモリ安全保障はコンパイル時に強制されていた
が、闇のRustの言語機能である、unsafe Rustと呼ばれる、普通のRustのように動くが、おまけの強大な力を与えてくれる

unsafeコードを使用してコンパイラに信じてもらうように教える
欠点はunsafeコードを誤るとnullポインタ参照外しなどメモリ非安全になる

Rustいunsafeな分身がある別の理由は、根本にあるコンピュータのハードウェアが本質的にunsafeだから
なぜなら、Rustがunsafeな処理を行わせてくれなかたら、特定の仕事を行えなくなる
Rustは、低レベルなシステムプログラミングを許可する必要がある
直接OSと相互作用したり、独自のOSを書くことさえもできる
低レベルなシステムプログラミングに取り組むことは、言語の目標の１つになっている


## unsafeの強大な力

unsafe Rustに切り替えるには、unsafeキーワードを使用し、それからunsafeコードを保持する新しいブロックを開始する
safe Rustでは行えない4つの行動をunsafe Rustでは行え、これはunsafe superpowersと呼ばれる

- 生ポインタを参照外しする
- unsafeな関数やメソッドを呼ぶこと　
- 可変で静的な変数にアクセスしたり変更すること
- unsafeなトレイトを実装すること

unsafeコードで参照を使用しても、チェックはされる　
コンパイラによってメモリ安全性は確認されないが、unsafeブロック内でも、ある程度の安全性は得られる

unsafeは、そのブロックが必ずしもキケンだったり、絶対メモリ安全上の問題を抱えていることを意味するものではない
その意図は、プログラマとしてunsafeブロック内のコードがメモリに合法的にアクセスすることを保証する

unsafeで注釈さすることで、ブロック内にメモリ安全性に関するエラーがあることを知ることができる

unsafeなコードをできるだけ分離するために、unsafeなコードを安全な抽象の中に閉じ込め、安全なAPIを提供するのが最善
標準ライブラリの一部は、検査されたunsafeコードの安全な抽象として実装されている
安全な抽象にunsafeなコードを包むことで、unsafeが、あなたやあなたのユーザがunsafeコードで実装された機能を使いたがる可能性のある箇所全部に漏れ出ることを防ぐ


### 生ポインタを参照外しする

参照同様、生ポインタも不変や可変になり得て、それぞれ*const Tと*mut Tと表記される
このアスタリスクは、参照外し演算子ではなく、型名の一部

#### 生ポインタとは

- 同じ場所への不変と可変なポインタや複数の可変なポインタが存在することで借用規則を無視できる
- 有効なメモリを指しているとは保証されない
- nullの可能性がある
- 自動的な片付けは実装されていない

これらの保証をコンパイラに強制させることから抜けることで、保証された安全性を諦めてパーフォマンスを向上させたり、Rustの保証が適用されない他の言語やハードウェアとのインタフェイスの能力を得ることができる

```rust:参照から生ポインタを生成する

// このコードにはunsafeキーワードを含めいていない
// safeコードで生ポインタを生成できる
// つまり、unsafeブロックの外では、生ポインタを参照外しできないだけ
let mut num  = 5;

let r1 = &num as *const i32;
let r2 = &mut num as *mut i32;
```

```rust:unsafeブロック内で生ポインタを参照外しする

fn main() {
	let mut num = 5;

	let r1 = &num as *const i32;
	let r2 = &mut num as *mut i32;

	unsafe {
		println!("r1 is: {}", *r1);
		println!("r2 is: {}", *r2);
	}
}

```

ポインタの生成は害を及ぼさない
害になるのは、無効な値を扱うことに落ち着く可能性のあるポインタが指している値にアクセスしようとする時のみ　

```rust:任意のメモリアドレスへの生ポインタを生成する
let address = 0x012345usize;
let r = address as *const i32;
```


### unsafeな関数　
 
```rust
unsafe fn dangerous(){}

// ブロック内で使用する
unsafe {
	dangerous()
}
```


### unsafeコードに安全な抽象を行う

```rust:安全なsplit_at_mut関数を使用する
let mut v = vec![1, 2, 3, 4, 5, 6];

let r = &mut v[..];

let (a, b) = r.split_at_mut(3);

assert_eq!(a, &mut [1, 2, 3]);
assert_eq!(b, &mut [4, 5, 6]);
```

この関数はsafe Rustだけでは実装できない

```rust
fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = slice.len();

    assert!(mid <= len);

    (&mut slice[..mid],
     &mut slice[mid..])
}

// output
error[E0499]: cannot borrow `*slice` as mutable more than once at a time
(エラー: 一度に2回以上、`*slice`を可変で借用できません)
 -->
  |
6 |     (&mut slice[..mid],
  |           ----- first mutable borrow occurs here
7 |      &mut slice[mid..])
  |           ^^^^^ second mutable borrow occurs here
8 | }
  | - first borrow ends here
```

```rsut:split_at_mut関数の実装でunsafeコードを使用する
use std::slice;

fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = slice.len();
    let ptr = slice.as_mut_ptr();

    assert!(mid <= len);

    unsafe {
        (slice::from_raw_parts_mut(ptr, mid),
         slice::from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
    }
}
```

スライスはなんらかのデータへのポインタとスライス長
lenメソッドを使用してスライスの長さを得て、as_mut_ptrメソッドを使用してスライスの生ポインタにアクセスする

mid添字がスライス内にあるかというｱｻｰﾄを残す
そして、unsafeコード内で、slice::from_raw_parts_mut関数で、生ポインタと長さを取り、スライスを生成する
この関数を使って、ptrから始まり、midの長さのスライスを生成する
それからptrにmidを引数として、offsetメソッドを呼び出し、midで始まる生ポインタを得て、そのポインタとmidの後の残りの要素数を長さとして使用してスライスを生成する


```rust:任意のメモリアドレスからスライスを生成

use std::slice;

let address = 0x012345usize;
let r = address as *mut i32;

let slice = unsafe {
	slice::from_raw_parts_mut(r, 1000)
};

```

この任意の場所のメモリは所有していなく、このコードが生成するスライスに有効なi32値が含まれる保証もない
sliceを有効なスライスであるかのように使用すると、未定義動作に陥る


### extern関数を使用して、外部のコードを呼び出す

自分のRustコードが他の言語で書かれたコードと相互作用する必要が出てきた時にexternはFFI(Foreign Function Interface:外部関数インタフェース)の生成と使用を容易にする

FFIはあるプログラミング言語に関数を定義させ、異なる（外部の）プログラミング言語にそれらの関数を呼び出すことを可能にする方法

externブロック内で宣言された関数は、常にRustコードから呼ぶにはunsafeになる
理由は、他の言語では、Rustの規則や保証が強制されず、コンパイラもチェックできないので、安全性を保証する責任はプログラマに降りかかる

```rust
extern "C" {
	fn abs(input: i32) -> i32;
}

fn main() {
	unsafe {
		// 引数をi32で定義したのに
		// -3を入れてエラーにならない
		println!("{}", abs(-3));
	}
}
```


```rust:他の言語からRustの関数を呼び出す
#[no_mangle]
pub extern "C" fn call_from_c() {
     // CからRust関数を呼び出したばかり！
    println!("Just called a Rust function from C!");
}
```

この場合、externの使用法では、unsafeは必要ない


### 可変で静的な変数にアクセスしたり、変更する

```rust
static mut COUNTER: u32 = 0;

fn add_to_count(inc: u32) {
	COUNTER += inc; // エラー
}
```

グローバルにアクセス可能な可変なデータはunsafeブロックでしか変更できない
シングルスレッドであれば、多少の安全性はあるが、マルチスレッドであれば、データ競合になる可能性が高い

```rust
static mut COUNTER: u32 = 0;

fn add_to_count(inc: u32) {
	unsafe {
		COUNTER += inc; // Ok
	}
}
```


### unsafeなトレイトを実装する

少なくとも、１つのメソッドにコンパイラが確かめられない何らかの不変条件があると、トレイとはunsafeになる
traitの前にunsafeキーワードを追加し、トレイとの実装もunsafeでマークすることで、トレイトがunsafeであると宣言できる

```rust
unsafe traint Foo {

}

unsafe impl Foo for i32 {

}
```


## 高度なライフタイム

- ライフタイム・サブタイピング
  - あるライフタイムが他のライフタイムより長生きすることを保証する

- ライフタイム境界
  - ジェネリックな型への参照のライフタイムを指定する

- トレイとオブジェクトのライフタイムの推論
  - コンパイラにトレイトオブジェクトのライフタイムを推論させることと指定する必用があるタイミング


### ライフタイム・サブタイピングにより、あるライフタイムが他よりも長生きすることを保証する

```rust

struct Context<'s>(&'s str);

// Contextでライフタイム'sと参照されたデータは、制限され、ライフタイム'cの参照よりも長生きすることを保証する必用がある
// 'sが'cより長くないと,Contextへの参照は合法ではない可能性がある
struct Parser<'c, 's: 'c> {
	context: &'c Context<'s>,
}

impl<'c, 's> Parser<'c, 's> {
	fn parse(&self) -> Result<(), &'s str> {
		Err(&self.context.0[1..])
	}
}

fn parse_context(context: Context) -> Result<(), &str> {
	Parser { context: &context }.parse()
}


### ジェネリックな型への参照に対するライフタイム境界

ライフタイム境界は、コンパイラが、ジェネリックな型の中の参照が参照先のデータよりも長生きしないことを確かめる手助けをする

```rust

struct Ref<'a, T>(&'a T); // エラー

// 明示的にジェネリック引数Tと関連してライフタイム'aを制限しないと、ジェネリックな型Tがどれだけ生きるのかわからないのでエラーになる
struct Ref<'a, T: 'a>(&'a T) // Ok

// Tに'staticライフタイム教会を追加してTを'static参照だけがあるか参照なしの型に制限する
struct StaticRef<T: 'static>(&'static T);

```


### トレイトオブジェクトライフタイムの推論

- トレイトオブジェクトのデフォルトのライフタイムは 'static
- &'a Traitや&'a mut Traitに関して、トレイトオブジェクトのデフォルトライフタイムは'a
- 単独のT: 'a節について、トレイトオブジェクトのデフォルトのライフタイムは'a
- 複数のT: 'aのような節について、デフォルトのライフタイムはない。明示しなければならない。


```rust

trait Red {}

struct Ball<'a> {
	diameter: &'a i32,
}

impl<'a> Red for Ball<'a> {}

fn main() {
	let num = 5;
	let obj = Box::new(Ball { diameter: &num }) as Box<Red>;
}
```

明示しなければならない時、Box<Red>のようなトレイトオブジェクトに対して、参照がプログラム全体で生きるかどうかにより、記法Box<Red + 'static>かBox<Red + 'a>を使用してライフタイム境界を追加できる
他の境界同様、ライフタイム境界を追記する記法は、型の内部に参照があるRedトレイトを実装しているものは全て、トレイト境界に指定されるライフタイムがそれらの参照と同じにならなければならないことを意味する


## 高度なトレイト


### 関連型でトレイト定義においてプレースホルダーの型を指定する

この章の中の他の機能と比べ、よく使われるのが関連型

関連型は、トレイトのメソッド定義がシグニチャでプレースホルダーの型を使用できるように、トレイトと型のプレースホルダーを結びつける
トレイトを実装するものがこの特定の実装で方の位置に使用される具体的な型を指定する
そうすることで、なんらかの型を使用するトレイトをトレイトを実装するまでその方が一体なんであるかを知る必要がなく定義できる


```rust:関連型があるトレイトの一例

pub trait Iterator {
	type Item;

	fn next(&mut self) -> Option<Self::Item>;
}
```

型Itemはプレースホルダー型でnextメソッドの定義は、型Option<Self::Item>の値を返すことを示している
Iteratorトレイトを実装するものは、Itemの具体的な型を指定し、nextメソッドは、その具体的な方の値を含むOptionを返す


ジェネリクスと関連型の違い

```rust:関連型

impl Iterator for Counter {
	type Item = u32;

	fn next(&mut self) -> Option<Self::Item> {
		// snip
	}
}
```

```rust:ジェネリクス

pub tarit Iterator<T> {
	fn next(&mut self) -> Option<T>;
}
```

ジェネリクスを使用すると、各実装で型を注釈しなければならない
面倒に思えるが、発想を変えれば、CounterのIteratorの実装を複数作ることができるといえる
換言すれば、トレイトにジェネリックな引数があると、毎回ジェネリックな型引数の具体的な型を変更してある型に対して複数回実装できるということ
Counterに対してnextメソッドを使用する際に、どのIteratorの実装を使用したいか型注釈をつけなければならない

関連型なら、同じ型に対してトレイトを複数回実装できないので、型を注釈する必要はない


### デフォルトのジェネリック型引数と演算子オーバーロード

Rustでは、独自の演算子を作ったり、任意の演算子をオーバーロードすることはできないが、演算子に紐付いたトレイトを実装することでstd::opsに列挙された処理と対応するトレイトをオーバーロードできる

```rust:+演算子をオーバーロードして２つのPointインスタンスを足し合わせる

use std::ops::Add;

#[derive(Debug, PartialEq)]
struct Point {
	x: i32,
	y: i32,
}

impl Add for Point {
	type Output = Point; // OutputはAddトレイトの関連型

	fn add(self, other: Point) -> Point {
		Point {
			x: self.x + other.x,
			y: self.y + other.y,
		}
	}
}

fn main() {
	assert_eq!(
		Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
		Point { x: 3, y: 3 }
	);
}
```

std::ops::Addトレイトには、addメソッドから返却される型を決定するOutputという関連型がある

```rust

trait Add<RHS=Self> {
	type Output;

	fn add(self, rhs: RHS) 　-> Self::Output;
}

RHS=Selfこれはデフォルト型引数
RHS(right hand side)というジェネリックな型引数が、addメソッドのrhs引数の型を定義している
Addトレイトを実装する際にRHSの具体的な型を指定しなれば、RHSの型は標準でSelfになり、これはAddを実装している型


```rust

use std::ops::Add; // Addトレイトを追加

// Addトレイトの定義
// trait Add<RHS=Self> {
//     type Output;

//     fn add(self, rhs: RHS) -> Self::Output;
// }

struct Millimeters(u32);
struct Meters(u32);

// Selfという規定を使うかわりにimpl Add<Meters>を指定して、RHS型のデフォルト引数の値をセットしている
impl Add<Meters> for Millimeters {
	type Output = Millimeters;

	fn add(self, other: Meters) -> Millimeters {
		Millimeters(self.0 + (other.0 * 1000))
	}
}

fn main() {
	let meters = Meters(1);
	let millmeters = Millimeters(1000);
	let added_meters_for_millmeters = millmeters.add(meters);
	println!("{:?}", added_meters_for_millmeters.0);
}

// output
// 2000
```


デフォルト型引数の使いどころ

- 既存のコードを破壊せずに型を拡張する
- ほとんどのユーザは必要としない特定の場合でカスタマイズを可能にする



### 明確化のためのフルパス記法:  同じ名前のメソッドを呼ぶ

Humanのインスタンスに対して複数のfly()メソッドが存在する場合、直接実装されたメソッドを標準で呼び出す

```rust
trait Pilot {
	fn fly(&self);
}

trait Wizard {
	fn fly(&self);
}

struct Human;

impl Pilot for Human {
	fn fly(&self) {
		// キャプテンのお言葉
		println!("This is your captain speaking.");
	}
}

impl Wizard for Human {
	fn fly(&self) {
		// 上がれ！
		println!("Up!");
	}
}

impl Human {
	fn fly(&self) {
		// *激しく腕を振る*
		println!("*waving arms furiously*");
	}
}

fn main() {
	let person = Human;
	person.fly();
}

// output
// *waving arms furiously*

```

```rust:どのトレイトのflyメソッドを呼びたいか指定する
fn main() {
	Pilot::fly(&person);
	Wizard::fly(&person);
}

//output
// *waving arms furiously*
// This is your captain speaking.

```

```rust:関連関数のあるトレイトとそのトレイトも実装し、同じ名前の関連関数がある型

trait Animal {
    fn baby_name() -> String;
}

struct Dog;

impl Dog {
    fn baby_name() -> String {
        // スポット(Wikipediaによると、飼い主の事故死後もその人の帰りを待つ忠犬の名前の模様)
        String::from("Spot")
    }
}

impl Animal for Dog {
    fn baby_name() -> String {
        // 子犬
        String::from("puppy")
    }
}

fn main() {
    // 赤ちゃん犬は{}と呼ばれる
    println!("A baby dog is called a {}", Dog::baby_name());
}
```

```rust:Animal::baby_nameを呼ぼうとするとエラー
fn main() {
    println!("A baby dog is called a {}", Animal::baby_name());
}
```

```rust:フルパス記法を用いてDogに対してAnimal実装を使用したいと明確化してコンパイラにわからせる
fn main() {
    println!("A baby dog is called a {}", <Dog as Animal>::baby_name());
}

// output
// A baby dog is called a puppy
```


### スーパートレイトを使用して別のトレイト内で、あるトレイト機能を必要とする

```rust
use std::fmt;

trait OutlinePrint: fmt::Display {
    fn outline_print(&self) {
        let output = self.to_string();
        let len = output.len();
        println!("{}", "*".repeat(len + 4));
        println!("*{}*", " ".repeat(len + 2));
        println!("* {} *", output);
        println!("*{}*", " ".repeat(len + 2));
        println!("{}", "*".repeat(len + 4));
    }
}
```

```rust:OutlinePrintトレイトをPoint構造体に実装する
struct Point {
    x: i32,
    y: i32,
}

impl OutlinePrint for Point {}

// error
error[E0277]: the trait bound `Point: std::fmt::Display` is not satisfied
  --> src/main.rs:20:6
   |
20 | impl OutlinePrint for Point {}
   |      ^^^^^^^^^^^^ `Point` cannot be formatted with the default formatter;
try using `:?` instead if you are using a format string
   |
   = help: the trait `std::fmt::Display` is not implemented for `Point`
```

```rsut:Pointにエラーの要求を満たすためにDisplayトレイトをPointに実装する

use std::fmt;

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}
```


### ニュータイプパターンを使用して外部の型に外部のトレイトを実装する


```rust
use std::fmt;

struct Wrapper(Vec<String>);

impl fmt::Display for Wrapper {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "[{}]", self.0.join(", "))
	}
}

fn main() {
	let v = vec!["hello", "world"];
	let w = Wrapper(vec![String::from("hello"), String::from("world")]);
	println!("{}", v); // エラー
	println!("{}", w); 
}

// output
// [hello, world]
```

Displayの実装は、self.0の中身のVec<T>にアクセスしている
Wrapperはタプル構造体でVec<T>がタプルの添字0の要素だから
それから、Wrapperに対してDisplay型の機能を使用している

このテクニックの欠点は、Wrapperが新しい型なので、保持している値のメソッドがない
self.0に委譲して、WrapperをVec<T>と全く同様に扱えるように、Wrapperに直接Vec<T>のすべてのメソッドを実装しなければならない


## 高度な型

### 型安全性と抽象化を求めてニュータイプパターンを使用する

静的に絶対に値を混同しないことを強制したり、値の単位を示すことを含む

型の実装の詳細を抽象化する際にニュータイプパターンを使用する
例えば、新しい型を直接使用して、利用可能な機能を制限したら、非公開の内部の型のAPIとは異なる公開APIを新しい型は露出できる

ニュータイプは内部の実装を隠匿することもできる
例えば、People型を提供して、人のIDと名前を紐付けて各脳するHashiMap<i32, String> をラップすることができる
Peopleを使用するコードは、名前の文字列をPeopleコレクションに追加するメソッドなど、提供している公開APIとだけ相互作用する
そのコードは、内部でi32IDを名前に代入していることを知る必要はない
ニュータイプパターンは、カプセル化を実現して実装の詳細を隠匿する軽い方法


### 型エイリアスで型同義語を生成する

```rust
fn main() {
	type Kilometers = i32;

	let x: i32 = 5;
	let y: Kilometers = 5;

	// i32とKilometersは同義語になり計算が可能
	println!("{}", x + y);
}

// output
// 10
```

型同義語の主なユースケースは、繰り返しを減らす


```rust:長ったらしい型や関数シグニチャ
let f: Box<Fn() + Send + 'static> = Box::new(|| println!("hi"));

fn takes_long_type(f: Box<Fn() + Send + 'static>) {
    // --snip--
}

fn returns_long_type() -> Box<Fn() + Send + 'static> {
    // --snip--
}
```

```rust:型エイリアスで繰り返しを減らす
type Thunk = Box<Fn() + Send + 'static>;

let f: Thunk = Box::new(|| println!("hi"));

fn takes_long_type(f: Thunk){};
fn returns_long_type() -> Thunk {};
```


Result<T, E>型で型エイリアスを使う

```rust:型エイリアスなし

use std::io::Error;
use std::fmt;

pub trait Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize, Error>;
    fn flush(&mut self) -> Result<(), Error>;

    fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>;
    fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Error>;
}
```

```rust:型エイリアスあり
type Result<T> = Result<T, std::io::Error>;

pub trait Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize>;
    fn flush(&mut self) -> Result<()>;

    fn write_all(&mut self, buf: &[u8]) -> Result<()>;
    fn write_fmt(&mut self, fmt: Arguments) -> Result<()>;
}
```


### never型を活かす

Rustでは、型論理用語で値がないため、空型としてしられる!という特別な型がある
関数が絶対に帰らない時に戻り値の型の場所に立つのでnever typeと呼ぶ

```rust:never型をつかう

let guess: u32 = match guess.trim().parse() {
	Ok(num) => num,
	Err(_) => continue, // !値
}

```rust:エラー
// Rustでは、matchは全て同じ型を返さなければならない
let guess = match guess.trim().parse() {
    Ok(_) => 5,
    Err(_) => "hello",
}
```


```rust:panic!マクロと使うと便利

impl<T> Option<T> {
	pub fn unwrap(self) -> T }{
		match self{
			Some(val) => val,
			None => panic!("called `Option::unwarp()` on a `None` value),
		}
	}
}

```


### 動的サイズ付け型とSizedトレイト

DTSやサイズなし型とも称され、実行時にしかサイズを知ることのできない値を使用するコードを書くことができる

Rustのコンパイラは特定の型の値１つにどれくらいのメモリスペースを確保するかなど特定の詳細を知りたがる

`str`は動的サイズ付け型といい、この型により、実行時にしかサイズを知ることのできない値を使用するコードを書くことができる

`&str`は文字列スライスといい、開始地点とスライスの長さを格納している

```rust:str
// こんにちは
let s1: str = "Hello there!"; // 12バイトのストレージが必要
// 調子はどう？
let s2: str = "How's it going?"; // 15バイトのストレージが必要
```

したがって、&Tは、Tがどこにあるのかのメモリアドレスを格納する単独の値だけれども、&strは２つの値、つまり、strのアドレスとその長さ
そのため、コンパイル時に&strのサイズを知ることができる
usizeの長さの2倍のメモリスペースを確保している(ちょっと無駄だよね!使うの控えねば...)


```rust:こんな感じのジェネリック関数定義は
fn generic<T>(t: T) {
	// --snip--
}
```
```rust:実際には内部ではこのように扱われている
fn generic<T: Sized>(t: T) {
	// --snip--
}
```

Sizedトレイトは、型のサイズがコンパイル時にわかるかどうかを決定する
コンパイル時にサイズの判明する全てのものに自動的に実装されている
加えて、コンパイラは暗黙的に全てにジェネリックな関数にSizedの境界を追加する


## 高度な関数とクロージャ

```rust
fn add_one(x: i32) -> i32 {
    x + 1
}

fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
    f(arg) + f(arg)
}

fn main() {
    let answer = do_twice(add_one, 5);

    // 答えは{}
    println!("The answer is: {}", answer);
}
```

クロージャと異なり、fnはトレイトではなく型なので、トレイト境界としてFnトレイトの１つでジェネリックな型引数を宣言するのではなく、直接fnを引数の型として指定する

関数ポインタは、クロージャトレイと３つ全て(Fn, FnMut, FnOnce)を実装するので、常に関数ポインタを引数として、クロージャを期待する関数に渡すことができる
関数が関数とクロージャどちらも受け入れられるように、ジェネリックな型とクロージャトレイとの１つを使用して関数を書くのが最善

クロージャではなくfnだけを受け入れたくなる箇所の1例は、クロージャのない外部コードとのインタフェース
C関数は引数として関数を受け入れられるが、Cにはクロージャがない


```rust

let list_of_numbers = vec![1, 2, 3];
let list_of_strings: Vec<String> = list_of_numbers
    .iter()
    .map(|i| i.to_string())
    .collect();
```


```rust
let list_of_numbers = vec![1, 2, 3];
let list_of_strings: Vec<String> = list_of_numbers
    .iter()
    .map(ToString::to_string) 
    .collect(); 
```

map関数のToString::to_stringにするのは、フルパス記法(他にもto_stringという利用可能な関数は複数あるので)


### クロージャを返す

```rust:Sizedトレイトのエラー
fn returns_closure() -> Fn(i32) -> i32 {
    |x| x + 1
}

// output
error[E0277]: the trait bound `std::ops::Fn(i32) -> i32 + 'static:
std::marker::Sized` is not satisfied
 -->
  |
1 | fn returns_closure() -> Fn(i32) -> i32 {
  |                         ^^^^^^^^^^^^^^ `std::ops::Fn(i32) -> i32 + 'static`
  does not have a constant size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for
  `std::ops::Fn(i32) -> i32 + 'static`
  = note: the return type of a function must have a statically known size
```

note: the return type of a function must have a statically known size とあるように、クロージャを格納するのに必要なスペースを明確にする必要があると注釈がある


```rust:Ok
fn returns_closure() -> Box<Fn(i32) -> i32> {
    Box::new(|x| x + 1)
}
```