[back]

2023-01-01 15:20:17 +09:00

# 雑記

## なぜOptionをletで扱えるのか

TL;DR

Some(T)がタプル構造体だから(だと思う)。 Rust弱者が無理して考えたら余計分からなくなった。読む価値はないです

let some_string: Option<&str> = Some("こんな感じのコードを");

if let Some(string) = some_string {
    println!("{}よく見かける", string);
} 

ちょっと突っ込んだコードをRustで書こうとするとResultとOptionからは逃れられないわけで、雰囲気で使ってるのを改めたかった。

そもそもOptionとは

RustでNullを表現できる感じの列挙体で、値はSome(T)Noneを取る…みたいな理解をしてる。 ファイルをロードしたりとかで値が無になりうる処理の返り値はこれに包む。

Rustのパターンマッチング

let x = 0という文では、letの右辺でパターンマッチングがされてる(らしい)。 The Bookによると、let a = bはつまるところlet パターン = 式をやってるっぽい。 左辺のパターンに右辺の式がマッチしたら束縛するとかなんとか。 で、上のコードif let Some~云々はこれをifにしただけであって"もしもletによるマッチが成功したら"後ろのブロックを実行するみたいな感じ? ここまで書いてて思ったことがあるので試す。

if let 1 = 1 {
    println!("これは通る?");
}

ちゃんとif letは成功して中身のprintln!が実行される。これをifを除いてlet 1 = 1;にすると通らないんだけど、1は変数じゃなく束縛できない相手(リテラル)だから落ちてるみたいな認識でいいんだろうか。The Book途中で読むのやめちゃったせいで理解甘い所あるなと思った、今度読み直す パターン記法では構造体とかも左辺に使えるからこんなコードも通る。

struct Pos {
    x: i32,
    y: i32,
}
let Pos { x, y } = Pos { x: -16, y: 0 };
println!("x: {}, y: {}", x, y);

これを省略していったのがlet x = Pos { x: -16, y: 0 }とかそういう一般的な変数の宣言っぽそう。 上の記法をOptionに当てはめるとlet Some(x) = Some(128)みたいな事になるわけで、右辺のSome(128)は左辺のSome(x)にマッチするので変数xに128が代入される。 ただ、Optionの場合はNoneの可能性がある(論駁可能性)のでletを平たく置いただけではコンパイルエラーになる。 だからif letとかlet~elseとしてパターンにマッチした場合のみ実行する必要があったんですね。

結論

Rustの仕様気持ち良すぎだろ!