Rust 1.65から使えるようになったlet else 制御文を試してみた。
Rust言語には、他の言語ではあまり見かけないようなif-let-elseのような便利な制御構文があるが、更にlet elseが追加された。
The Rust RFC Bookには
let-elseはrefutable(反駁可能)なlet文だと説明してる。let PATTERN: TYPE = EXPRESSION else DIVERGING_BLOCK;
実際のコードでやってみる。
/// Key number detect pattern with let-else
/// 例 "my_key: 123"
pub fn key_num(item: &str) -> Result<(&str, i32), &'static str> {
let Some((key, val)) = item.split_once(':') else {return Err("Invalid: item wrong format no : separator");};let Ok(val) = val.trim().parse::<i32>() else {return Err("Invalid: item value not i32");};Ok((key, val))}fn main() {let items = ["mykey : 123","mykey 123", //wrong: no separater"mykey : abcd",// wrong: not i32 val"secretkey: 0000",];for item in items.iter() {let (key, val) = key_num(item).unwrap();println!("key={} val={}", key, val);};}
文字キーと数字で構成される項目からキーと数値を検出するプログラムを考えてみる。
キーと数字は':'で分割されるとする。
"mykey : 123"のように
項目のフォーマットが正しくない場合はエラーを発生させる。
let Some((key, val)) = item.split_once(':') else {
return Err("Invalid: item wrong format no : separator");
};
プログラムを実行してみる。
unwrap()を使わないでエラー処理を追加する。
};
プログラムを実行してみる。
このコードでは不正な項目が見つかると、unwrap()ではエラー処理がないのでmainはpanicで終了する。Compiling rust-let-else v0.1.0 (/home/mycat/projects/rust-let-else)Finished dev [unoptimized + debuginfo] target(s) in 0.10sRunningkey=mykey val=123thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "Invalid: item wrong format no : separator"', src/main.rs:23:40note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
unwrap()を使わないでエラー処理を追加する。
for item in items.iter() {let result = key_num(item);match result {Ok((key,val)) =>{println!("key={:?} val={:?}", key, val)},Err(error) => {println!("There was a problem key number: {}", error)},};
};
Compiling rust-let-else v0.1.0 (/home/mycat/projects/rust-let-else)Finished dev [unoptimized + debuginfo] target(s) in 0.10sRunning
key="mykey " val=123There was a problem key number: Invalid: item wrong format no : separatorThere was a problem key number: Invalid: item value not i32key="secretkey" val=0
これでエラー処理を含めて実行できた。めでたし、めでたし。
注意したいのはelse文にはreturn,break,continueなどの型のないdiverging(発散する)なブロックしか使えない。
ここがif-let-elseとの違い。
基本的にelseには異常時の処理を記述することになる。
ちなみに、画像の3匹の猫はrustのstable diffusion(画像生成AI)diffusers-rsで生成したものです。