0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Effective-Rustlings-jp】Day 3:OptionとResultに対してはmatchを用いずに変換しよう

Last updated at Posted at 2025-01-03

はじめに

こんにちは。細々とプログラミングをしているsotanengelです。
この記事は以下の記事の連載です。

他の連載記事 (詳細)

また本記事はEffective Rust(David Drysdale (著), 中田 秀基 (翻訳))を参考に作成されております。とてもいい書籍ですので興味を持った方は、ぜひ読んでみてください!

今日の内容

概要

Day1の記事でenumとmatchを使って、effectiveな書き方を実行していましたが、必ずしもmatchを使えばいいというわけではありません。その例を今回の問題で見ていきましょう。

if letで不要な条件分岐の処理を省略する

問(リンク)

Option型の変数において「Noneの処理が必要ない」場合にはif letを使いましょう。

コード (詳細)
fn main() {
    let value: Option<i32> = Some(42);

    // TODO: Noneの場合の処理は必要ないのでifを使った処理に変更してください。
    match value {
        Some(x) => println!("Found: {}", x),
        None => println!("No value found."),
    }
}

解答(リンク)

コード参照。

コード (詳細)
fn main() {
    let some_value: Option<i32> = Some(42);

    // 値がある場合だけ処理を行う
    if let Some(x) = some_value {
        println!("Found: {}", x);
    }
}

致命的なエラーを簡潔に処理する

問(リンク)

致命的なエラーが生じた時にはmatchを使わなくとも簡潔に表現できるメソッドがRustにはあります。そのメソッドでコードを短縮しましょう。

コード (詳細)
fn main() {
    let value: Option<i32> = Some(42);

    // TODO: expectを使って冗長な処理を簡潔にしてください。
    match value {
        Some(num) => println!("The value is: {}", num),
        None => panic!("Something wrong !"),
    };
}

解答(リンク)

コード参照。

コード (詳細)
#[allow(clippy::unnecessary_literal_unwrap)]
fn main() {
    let value: Option<i32> = Some(42);

    let result = value.expect("Something wrong !");
    println!("The value is: {}", result);
}

Result型は使用すること

問(リンク)

Result型は使用しないとコンパイルで警告が出ます。
使用して警告を解消しましょう。

コード (詳細)
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 {
        Err("Division by zero is not allowed")
    } else {
        Ok(a / b)
    }
}

fn main() {
    let result = divide(10, 0);

    // TODO: 返却されたResult型は使用する必要があります。
    // matchを使って、計算結果を表示してください。
    println!("result is Error");
}

解答(リンク)

コード参照。

コード (詳細)
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 {
        Err("Division by zero is not allowed")
    } else {
        Ok(a / b)
    }
}

fn main() {
    let result = divide(10, 0);

    match result {
        Ok(value) => println!("Result: {}", value),
        Err(e) => println!("Result: {}", e),
    }
}

?を使って簡潔に処理しよう

問(リンク)

Result型にクエスションマークを使うとエラーを伝播することができます。
match部分をクエスションマークに置き換えましょう。

コード (詳細)
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 {
        Err("Division by zero is not allowed")
    } else {
        Ok(a / b)
    }
}

fn main() {
    let result = divide(10, 3); // TODO: クエスションマークを使ってさらに簡潔に表現しましょう。

    match result {
        Ok(value) => println!("Result: {}", value),
        Err(e) => panic!("Result: {}", e),
    }
}

解答(リンク)

コード参照。

コード (詳細)
fn divide(a: i32, b: i32) -> Result<i32, &'static str> {
    if b == 0 {
        Err("Division by zero is not allowed")
    } else {
        Ok(a / b)
    }
}

fn main() -> Result<(), &'static str> {
    let value = divide(10, 3)?; // クエスションマークでエラーハンドリング
    println!("Result: {}", value);

    Ok(())
}

さいごに

もしも本リポジトリで不備などあれば、リポジトリのissueやPRなどでご指摘いただければと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?