###### 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;
}
}
```