###### tags: `Rust` # Rust テキスト学習 1 https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/variable-bindings.html を見て、足りない知識をメモる # 4. シンタックスとセマンティクス - syntax = 文法 - semantics = 意味論。そのコードを実行するとどんな意味があるのか ## 変数束縛 - 変数束縛 = 何らかの値を変数名に束縛すること Rustでは、1つの値(リソース)に1つの名前が対応するので 他の言語と逆(普通は変数名を値に束縛する) - 型アノテーション = let i **: i32** <- ここの部分 - パターン = let式の左側、単なる変数名ではない let (x, y) = (1, 2) いろいろなことができる ### スコープとシャドーイング - スコープ = 変数の寿命 - シャドーイング = スコープ外の変数束縛をスコープ内で書き換える(隠す)こと ## 関数 - main() : エントリーポイント - 関数のフォーマット ```rust= fn func_name(arg1: type, arg2: type) -> return_type { /*code*/ } ``` - Rustの関数の戻り値 : 0 or 1つ - 最後の行の ; セミコロン : 省略すると、最後の行の式を行化した値が戻り値になる Rustは式ベース(expression based)な言語 何も返さない文(statement)はほぼ存在しない **宣言文** と **式文** の2種類のみが存在する。 つまり、関数fn, if, match, のすべてが何らかの値を返す。 {} で囲ったコードの最後の行の ; を省略することで戻り値として式を評価する(2種類だけ) - 宣言文 : letを使った変数束縛の文 宣言文を評価しても値を返さないので下の例はコンパイルエラー ```rust= let x = (let y = 5); ``` - 式文 : ; セミコロンをつけて文に変換された式 Rustにおいては、関数等のスコープで最後に評価される式までの途中式を指す 文のあとには文が続くことが期待される。 式を;で区切ることで、文とみなす。 最後には式を書いて、評価した値をreturnする。 ```rust= fn add_three(a: i32){ a += 1; // 式文 (途中式) a += 1; // 式文 a += 1; // 式文 a  // 式 } ``` - return文 : 早期return Rustは式ベースなので、return を使うほうが珍しい 関数の最後の行で使っても動くが、推奨されないスタイル ### 発散する関数 ! 発散する関数 = 値を返さない関数 diverges = 発散の意 - 発散する関数を作成する方法 : 戻り値を ! 型にする 下記の関数はクラッシュするので絶対値を返さない。 そのような関数は!型を持つ。 ```rust= fn diverges() -> ! { panic!("この関数は戻り値を返さない"); } ``` - **panic!(str)** : 実行中のスレッドを与えたメッセージとともにクラッシュする。 実は関数ではなくマクロ クラッシュを引き起こした関数は値を返さずに終了する。 - **println!(str)** これも関数ではなくマクロ ### 関数ポインタ 関数を変数に入れる。 別名をつけたり、配列に入れて管理できる。 ```rust= let f: fn(i32) -> i32 = plus_one; f(100) ``` ## Primitive型 - bool - char Rustのcharは1バイトではなく4バイト UTF-8なので絵文字やひらがなも扱える。 ```rust= let a = 'あ'; let heart = '💓'; println!("{} {}", a, heart); ``` - Integer - i8/16/32/64 - u8/16/32/64 - isize : 動作しているマシンのポインタサイズと同じ整数値 4Gb Ram なら -2G ~ 2G - usize : 上の符号なしバージョン isizeとusizeは可変長型であり、マシンのポインタサイズにより処理が異なる場合に便利 - Float - f32/64 - Array - 配列の型 : [T; N] Tはジェネリック型、Nは要素数 - 省略記法 : 配列各要素を同じ値で初期化するための簡略記法 ```rust= let arr = [0; 20]; // サイズ20の配列を0で初期化 ``` - arr.len() : 配列の長さを返す - Slice - Sliceとは、他のデータ構造の参照 - コピーせずに安全で効率的なアクセスを可能にする - Sliceの型 : &[T] - str - 最もプリミティブな文字列型 - &strの形でよく使う - Tuple - 固定サイズ順序ありリスト - () で加工 - Tapleの型: (T, T, ...) - 異なる型を含める (i32, &str, ...) - let (x, y, z) = (1, 2, 3) - タプルの各要素を変数に割り当てる強力なパターン - tupleインデックス: tuple.0, tuple.1 ... - fn(T) -> T - 関数のType - 関数のポインタを入れることができる ## コメント // 行末まで /* 範囲 */ /// ドキュメンテーション(Markdownが使える) //! ドキュメンテーション(crateやmodにつける) ## if if式。式なので下のような使い方ができる。 if ~ else までを1行でかけるとスマート ```rust= let x = if condition {a} else {b}; ``` **elseのないif式** は戻り値が空のタプル()になるので注意 ## loop - loop : 無限ループ - while con : 条件ループ - for var in expression - expressionは IntoIteratorでイテレータに変換できる式 - 取り出せる値がなくなったら終了 ```rust= for i in 0..10 {} ``` - ループ回数を知る必要があるとき、 .enumerate()が使える ```rust= for (i, j) in (5..10).enumerate() { } ``` enumerate = 数え上げる、列挙する iterator.enumerate() : 要素とインデックスをタプルにしたイテレーターを返す。 ## loopの早期終了 - break - continue - return : loopを式とみなして値を評価できる。 ## ループラベル `'ラベル名:` loop/while/for キーワードの前に書ける break や continue のあとに書くことで、その位置から再開 or そのブロックから抜ける ```rust= 'outer: for x in 0..10 { 'inner: for y in 0..10 { break 'outer; } } ```