Open3
Effective Rustを1日1項目づつ読んで雑にメモをする
Item 3: Prefer Option and Result transforms to explicit match expressions
-
Option, Result
のNone/Err
に興味がない場合はmap/map_err, unwrap/expect, if let
を使う - メソッドに
#[must_use]
アノテーションをつけると戻り値のResult
を無視したときに警告を出せる - 特に
?
を使うとコード簡潔にすることができる。インライン化されてオーバーヘッドがないのでどんどん使おう - エラーの内容が呼び出し側にとって有益なら
Option
よりもResult
を使う -
Option<T>, Result<T, E>
とT
の変換チャート
Item 4: Prefer idiomatic Error types
- std::error::Errorの実装はほとんど人手がかからないので用途に応じて自分のエラーに対する実装をする
- ラップするエラーが複数の種類の場合はラップされる型の情報が必要かどうかで判断する
- 型が必要ないならanyhowを使い、アプリケーションコードに対して型を隠蔽する
- 型が必要ならenumでラップする。thiserrorが役に立つ
- 簡略化のため慣用的なエラーハンドリングにはanyhowの使用を検討する
- どんな決断であれ型システムで表現しよう
TIPS
ラップするエラー型に対してFromを実装しておくとmap_errしなくてよくなる
impl From<std::io::Error> for MyError {
fn from(e: std::io::Error) -> Self {
Self::Io(e)
}
}
impl From<std::string::FromUtf8Error> for MyError {
fn from(e: std::string::FromUtf8Error) -> Self {
Self::Utf8(e)
}
}
こんな感じで?
だけで自動的に変換される
/// Return the first line of the given file.
pub fn first_line(filename: &str) -> Result<String, MyError> {
let file = std::fs::File::open(filename)?; // via `From<std::io::Error>`
let mut reader = std::io::BufReader::new(file);
let mut buf = vec![];
let len = reader.read_until(b'\n', &mut buf)?; // via `From<std::io::Error>`
let result = String::from_utf8(buf)?; // via `From<std::string::FromUtf8Error>`
if result.len() > MAX_LEN {
return Err(MyError::General(format!("Line too long: {}", len)));
}
Ok(result)
}
Item 5: Understand type conversions
Rustには3種類の型変換がある
- 手動: ユーザーが定義した型変換で
From
とInto
traitで実現される - 半自動:
as
キーワードによる明示的なキャスト - 自動: 新しい型への暗黙的な型強制
FromとIntoによる型変換
- 変換に関する4つのtraitがある。すなわち
From<T>
、TryFrom<T>
、Into<T>
、TryInto<T>
である。 -
From<T> for U
からInto<U> for T
が導出される - 関数引数の型パラメータ境界に
fn some_func(t: T) -> () where T: Into<U>
とIntoを指定することで暗黙的な変換が行える
as
によるキャスト
as
によるキャストの対象は以下の2パターンしかない
- 数値のみを含むC-like enum
- 整数の変換
- 安全ではないので
into
またはfrom
を使うこと
- 安全ではないので
型強制
以下の6パターンがある
- 可変参照(
&mut T)
を非可変参照(& T
)に変換する - 参照をraw参照に変換する
- 変数をキャプチャしないクロージャを関数ポインタに変換する
- arrayをsliceに変換する
- 具象型をtrait オブジェクトに変換する
- アイテムのライフタイムを短いライフタイムに変換する