はじめに
こんにちは。細々とプログラミングをしている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などでご指摘いただければと思います。