let else

パターンにマッチさせて関数から返る一般的なケースでは、 let else を使います。 「else」側は発散しなければなりません(returnbreak、または panic。つまり、ブロックの末尾まで到達してそのまま抜けることはできません)。

// 著作権 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
    let s = if let Some(s) = maybe_string {
        s
    } else {
        return Err(String::from("None を受け取りました"));
    };

    let first_byte_char = if let Some(first) = s.chars().next() {
        first
    } else {
        return Err(String::from("空の文字列を受け取りました"));
    };

    let digit = if let Some(digit) = first_byte_char.to_digit(16) {
        digit
    } else {
        return Err(String::from("16進数の桁ではありません"));
    };

    Ok(digit)
}

fn main() {
    println!("結果: {:?}", hex_or_die_trying(Some(String::from("foo"))));
}
書き換えたバージョンは次のとおりです:
#![allow(unused)]
fn main() {
// 著作権 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn hex_or_die_trying(maybe_string: Option<String>) -> Result<u32, String> {
    let Some(s) = maybe_string else {
        return Err(String::from("None を受け取りました"));
    };

    let Some(first_byte_char) = s.chars().next() else {
        return Err(String::from("空の文字列を受け取りました"));
    };

    let Some(digit) = first_byte_char.to_digit(16) else {
        return Err(String::from("16進数の桁ではありません"));
    };

    Ok(digit)
}
}

さらに詳しく

  • この早期 return ベースの制御フローは、Result から値を取り出そうとし、 ResultErr だった場合にエラーを返す Rust のエラーハンドリングコードで よく見られます。
  • 学生から質問があれば、実際のエラーハンドリングコードを ? でどのように 書くかも示せます。