プログラミング言語Rust 「4.2. 関数」写経時のつぶやき
2018/12/11
fnは関数ということを示す
— ちゃまぐ (@tyamaguc07) 2018年12月11日
関数の引数はletと似た動きをする
引数の名前にコロンをつけて型を宣言する
letと異なり、関数の宣言に型は必須
Rustはあえて関数で型を明示するように設計されている
— ちゃまぐ (@tyamaguc07) 2018年12月11日
→ 型推論するようにすることも可能
→ Haskellは関数も型推論が動く
→ そのようなHaskellでもドキュメント目的で型を明示することは良い習慣だと言われている
関数戻り値の型は以下のように指定する
— ちゃまぐ (@tyamaguc07) 2018年12月11日
fn add_one(x: i32) -> i32 {
関数の最後の行が何を返すのか決定する
最後の行の末尾にセミコロンがあるとエラーになる
このエラーが示すことは2つある
①Rustが式ベースの言語であること
②セミコロンが他の「波括弧とセミコロン」ベースの言語と違うこと
Rustは主として式ベースの言語
— ちゃまぐ (@tyamaguc07) 2018年12月11日
文の書き方は2種類しかない
式と文の違い
・式は値を返すが、文は値を返さない
→ 関数の最後の行の末尾にセミコロンがあると文となり、値を返さないためエラーになる
・宣言文
— ちゃまぐ (@tyamaguc07) 2018年12月11日
変数束縛に使用するletを使うと宣言文となる
したがって、rubyなら動く以下のコードはRustではエラーになる
Ruby: x = y = 5
Rust: let x = (let y = 5) // expected expression, found statement `let’
エラーが伝える内容は、式を期待していたが、'let'文が見つかった
既に束縛されている変数への割当は式
— ちゃまぐ (@tyamaguc07) 2018年12月11日
let mut x = 5;
let y = x = 10; // x = 10は式
割当が割り当てられる値を評価する他の言語とは異なり、Rustでは割当の式が返す値はタプル
なぜなら、割り当てられる値には単一の所有者しかいないため、割り当てられる値を返せない。他の値を返すことも予想外。
したがって、以下の処理を実行するとyの値はタプルになる。
— ちゃまぐ (@tyamaguc07) 2018年12月11日
let mut x = 5;
let y = x = 10;
2018/12/12
・式文
— ちゃまぐ (@tyamaguc07) 2018年12月12日
式を文に変換する
Rustの文法は文のあとに文が続くことを期待する
式の末尾にセミコロンを入れることで文に変換する
したがって、Rustのコード「ほとんど」の行でセミコンが見られる
「ほとんど」の例外は、関数から値が返る場合
この場合、値を返したいのでセミコロンをつけない
returnキーワードを使うことでセミコロンが末尾にあっても、値を返せる
— ちゃまぐ (@tyamaguc07) 2018年12月12日
しかし、関数の最後でreturnキーワードを使って値を返すことは良くないスタイルと言われている
・発散する関数
— ちゃまぐ (@tyamaguc07) 2018年12月12日
「発散する関数」=値を返さない関数
発散する関数のための特別な構文がいくつかある
fn diverages() -> ! {
panic!("This function never returns!");
}
この関数はクラッシュするので決して値を返さない
そのためこの関数は返り値の方として!型を持つ
!はdivergesとよぶ
■ 関数ポインタ
— ちゃまぐ (@tyamaguc07) 2018年12月13日
関数を示す変数束縛を作る事ができる
let f: fn(i32) -> i32;
上記コードで定義されたfはi32を引数として、i32を返す関数を示す変数束縛。
よって以下のような事ができる
fn one_plus(i: i32) -> i32 {
i + 1
}
let f: fn(i32) -> i32 = one_plus;
変数束縛fを使って関数を実行できる
— ちゃまぐ (@tyamaguc07) 2018年12月13日
型推論は`type inference`というのか。
■ プリミティブ型
プリミティブ型は言語に組み込まれた型
■ ブーリアン型
boolと名付けられている型
trueとfalseの2つの値を持つ
■ char型
一つのユニコードのスカラ値を表す型
Rustのchar型は1byteでなく4byte