0. まとめ
用途別:
-
Ok
からOk
へおよびErr
からErr
への変換map
map_err
map_or_else
-
Ok
からErr
へおよびErr
からOk
への変換and_then
or_else
map_or_else
- 値同士を結合
and_then
or_else
- 参照
-
as_ref
,as_deref
,as_mut
,as_deref_mut
-
- 複製
-
clone
,clone_from
-
copied
,cloned
-
※ map_or
メソッドも map_or_else
メソッドと同じことができますが、値を遅延評価するために本記事では map_or_else
メソッドを使用します。
※ and
メソッドも and_then
メソッドと同じことができますが、値を遅延評価するために本記事では map_or_else
メソッドを使用します。
※ or
メソッドも or_else
メソッドと同じことができますが、値を遅延評価するために本記事では map_or_else
メソッドを使用します。
//
pub fn map<U>(self: Result<T, E>, op: impl FnOnce(T) -> U) -> Result<U, E>
pub fn map_err<F>(self: Result<T, E>, op: impl FnOnce(E) -> F) -> Result<T, F>
//
pub fn map_or_else<U>(self: Result<T, E>, default: impl FnOnce(E) -> U, f: impl FnOnce(T) -> U) -> U
//
pub fn and_then<U>(self: Result<T, E>, op: impl FnOnce(T) -> Result<U, E>) -> Result<U, E>
pub fn or_else<F>(self: Result<T, E>, op: impl FnOnce(E) -> Result<T, F>) -> Result<T, F>
//
pub fn as_ref(self: &Result<T, E>) -> Result<&T, &E>
pub fn as_deref(self: &Result<T, E>) -> Result<&T::Target, &E>
where
T: Deref,
pub fn as_mut(self: &mut Result<T, E>) -> Result<&mut T, &mut E>
pub fn as_deref_mut(self: &mut Result<T, E>) -> Result<&mut T::Target, &mut E>
where
T: DerefMut,
//
pub fn clone(self: &Result<T, E>) -> Result<T, E>
pub fn clone_from(self: &mut Result<T, E>, source: &Result<T, E>)
//
pub fn copied(self: Result<&T, E>) -> Result<T, E>
where
T: Copy,
pub fn cloned(self: Result<&T, E>) -> Result<T, E>
where
T: Clone,
pub fn copied(self: Result<&mut T, E>) -> Result<T, E>
where
T: Copy,
pub fn cloned(self: Result<&mut T, E>) -> Result<T, E>
where
T: Clone,
参考「map - Result in std::result - Rust」
参考「map_err - Result in std::result - Rust」
参考「map_or_else - Result in std::result - Rust」
参考「and_then - Result in std::result - Rust」
参考「or_else - Result in std::result - Rust」
参考「as_ref - Result in std::result - Rust」
参考「as_deref - Result in std::result - Rust」
参考「as_mut - Result in std::result - Rust」
参考「as_deref_mut - Result in std::result - Rust」
参考「clone - Result in std::result - Rust」
参考「clone_from - Result in std::result - Rust」
参考「copied - Result in std::result - Rust」
参考「cloned - Result in std::result - Rust」
参考「copied - Result in std::result - Rust」
参考「cloned - Result in std::result - Rust」
1. Ok
から Ok
へおよび Err
から Err
への変換
1.1. Result<T, E>
型から Result<U, E>
型への変換
Ok
の値のみ変換する場合は map
メソッドを用います。
let f = |t: i64| t.to_string();
let x1: Result<i64, i64> = Ok(23);
let x2: Result<i64, i64> = Err(42);
let y1: Result<String, i64> = x1.map(f);
let y2: Result<String, i64> = x2.map(f);
println!("{:?}", y1);
println!("{:?}", y2);
Ok("23")
Err(42)
1.2. Result<T, E>
型から Result<T, F>
型への変換
Err
の値のみ変換する場合は map_err
メソッドを用います。
let f = |e: i64| e.to_string();
let x1: Result<i64, i64> = Ok(23);
let x2: Result<i64, i64> = Err(42);
let y1: Result<i64, String> = x1.map_err(f);
let y2: Result<i64, String> = x2.map_err(f);
println!("{:?}", y1);
println!("{:?}", y2);
Ok(23)
Err("42")
1.3. Result<T, E>
型から Result<U, F>
型への変換
Ok
と Err
の両方の値を変換するメソッドは (少なくともバージョン 1.73.0 現在は) 標準では提供されないため、map_or_else
メソッドを用いて変換します。
(※ map_or
メソッドでも同様のことができますが、map_or
メソッドを用いると self
が Ok
の場合でも Err
用の引数の計算を正格評価で行ってしまうため、map_or_else
メソッドを用いて引数を遅延評価します。)
(※ map
メソッドと map_err
メソッドを組み合わせることでも同様のことができますが、最適化を考慮しない場合は計算コストが増加します。)
let f = |t: i64| t.to_string();
let g = |e: i64| e.to_string();
let x1: Result<i64, i64> = Ok(23);
let x2: Result<i64, i64> = Err(42);
let y1: Result<String, String> = x1.map_or_else(|e| Err(g(e)), |t| Ok(f(t)));
let y2: Result<String, String> = x2.map_or_else(|e| Err(g(e)), |t| Ok(f(t)));
println!("{:?}", y1);
println!("{:?}", y2);
Ok("23")
Err("42")
2. Ok
から Err
へおよび Err
から Ok
への変換
2.1. Result<T, E>
型から Result<U, E>
型への変換
Ok
の値を Ok
または Err
の値に変換する場合は and_then
メソッドを用います。
let f = |t: i64| if t >= 0 { Ok(t.to_string()) } else { Err(t) };
let x1: Result<i64, i64> = Ok(23);
let x2: Result<i64, i64> = Ok(-23);
let x3: Result<i64, i64> = Err(42);
let x4: Result<i64, i64> = Err(-42);
let y1: Result<String, i64> = x1.and_then(f);
let y2: Result<String, i64> = x2.and_then(f);
let y3: Result<String, i64> = x3.and_then(f);
let y4: Result<String, i64> = x4.and_then(f);
println!("{:?}", y1);
println!("{:?}", y2);
println!("{:?}", y3);
println!("{:?}", y4);
Ok("23")
Err(-23)
Err(42)
Err(-42)
2.2. Result<T, E>
型から Result<T, F>
型への変換
Err
の値を Ok
または Err
の値に変換する場合は or_else
メソッドを用います。
let f = |e: i64| if e >= 0 { Ok(e) } else { Err(e.to_string()) };
let x1: Result<i64, i64> = Ok(23);
let x2: Result<i64, i64> = Ok(-23);
let x3: Result<i64, i64> = Err(42);
let x4: Result<i64, i64> = Err(-42);
let y1: Result<i64, String> = x1.or_else(f);
let y2: Result<i64, String> = x2.or_else(f);
let y3: Result<i64, String> = x3.or_else(f);
let y4: Result<i64, String> = x4.or_else(f);
println!("{:?}", y1);
println!("{:?}", y2);
println!("{:?}", y3);
println!("{:?}", y4);
Ok(23)
Ok(-23)
Ok(42)
Err("-42")
2.3. Result<T, E>
型から Result<U, F>
型への変換
Ok
と Err
の相互変換をする場合は map_or_else
メソッドを用います。
let f = |t: i64| {
if t >= 0 {
Ok(t.to_string())
} else {
Err(t.to_string())
}
};
let g = |e: i64| {
if e >= 0 {
Ok(e.to_string())
} else {
Err(e.to_string())
}
};
let x1: Result<i64, i64> = Ok(23);
let x2: Result<i64, i64> = Ok(-23);
let x3: Result<i64, i64> = Err(42);
let x4: Result<i64, i64> = Err(-42);
let y1: Result<String, String> = x1.map_or_else(g, f);
let y2: Result<String, String> = x2.map_or_else(g, f);
let y3: Result<String, String> = x3.map_or_else(g, f);
let y4: Result<String, String> = x4.map_or_else(g, f);
println!("{:?}", y1);
println!("{:?}", y2);
println!("{:?}", y3);
println!("{:?}", y4);
Ok("23")
Err("-23")
Ok("42")
Err("-42")
3. 値同士を結合する
3.1. Result<T, E>
型から Result<U, E>
型への変換
and_then
メソッドは、2 値が両方とも Ok
なら Ok
を返し、それ以外は Err
を返す目的でも使用できます。
(※ and
メソッドでも同様のことができますが、and
メソッドを用いると self
が Err
の場合でも引数の計算を正格評価で行ってしまうため、and_then
メソッドを用いて引数を遅延評価します。)
let x1: Result<i64, &str> = Ok(23);
let x2: Result<i64, &str> = Err("Error: x");
let y1: Result<&str, &str> = x1.and_then(|_| Ok("Foo"));
let y2: Result<&str, &str> = x1.and_then(|_| Err("Error: y"));
let y3: Result<&str, &str> = x2.and_then(|_| Ok("Foo"));
let y4: Result<&str, &str> = x2.and_then(|_| Err("Error: y"));
println!("{:?}", y1);
println!("{:?}", y2);
println!("{:?}", y3);
println!("{:?}", y4);
Ok("Foo")
Err("Error: y")
Err("Error: x")
Err("Error: x")
3.2. Result<T, E>
型から Result<T, F>
型への変換
or_else
メソッドは、2 値のどちらか一方が Ok
なら Ok
を返し、それ以外は Err
を返す目的でも使用できます。
(※ or
メソッドでも同様のことができますが、or
メソッドを用いると self
が Ok
の場合でも引数の計算を正格評価で行ってしまうため、or_else
メソッドを用いて引数を遅延評価します。)
let x1: Result<&str, i64> = Ok("Foo");
let x2: Result<&str, i64> = Err(23);
let y1: Result<&str, &str> = x1.or_else(|_| Ok("Bar"));
let y2: Result<&str, &str> = x1.or_else(|_| Err("Error: y"));
let y3: Result<&str, &str> = x2.or_else(|_| Ok("Bar"));
let y4: Result<&str, &str> = x2.or_else(|_| Err("Error: y"));
println!("{:?}", y1);
println!("{:?}", y2);
println!("{:?}", y3);
println!("{:?}", y4);
Ok("Foo")
Ok("Foo")
Ok("Bar")
Err("Error: y")
4. 参照
Ok
および Err
の中身の値を借用します。
Ok
に関しては中身の値を借用かつ deref()
することもできます。
let x1: Result<String, i64> = Ok("Foo".to_string());
let x2: Result<String, i64> = Err(23);
//
let y1: Result<&String, &i64> = x1.as_ref();
let y2: Result<&String, &i64> = x2.as_ref();
let y1: Result<&str, &i64> = x1.as_deref();
let y2: Result<&str, &i64> = x2.as_deref();
let mut x1: Result<String, i64> = Ok("Foo".to_string());
let mut x2: Result<String, i64> = Err(23);
//
let y1: Result<&mut String, &mut i64> = x1.as_mut();
let y2: Result<&mut String, &mut i64> = x2.as_mut();
let y1: Result<&mut str, &mut i64> = x1.as_deref_mut();
let y2: Result<&mut str, &mut i64> = x2.as_deref_mut();
5. 複製
Ok
および Err
の外身の値を複製する場合は clone
メソッドまたは clone_from
メソッドを用います。
let x: Result<i64, i64> = Ok(23);
//
let y: Result<i64, i64> = x.clone();
let mut y: Result<i64, i64> = x.clone();
y.clone_from(&x);
Ok
の中身の値を複製する場合は copied
メソッドまたは cloned
メソッドを用います。
//
let value = 23;
let x: Result<&i64, i64> = Ok(&value);
let y: Result<i64, i64> = x.copied();
let value = 23;
let x: Result<&i64, i64> = Ok(&value);
let y: Result<i64, i64> = x.cloned();
//
let value = "Foo".to_string();
let x: Result<&String, i64> = Ok(&value);
let y: Result<String, i64> = x.cloned();
//
let mut value = 23;
let x: Result<&mut i64, i64> = Ok(&mut value);
let y: Result<i64, i64> = x.copied();
let mut value = 23;
let x: Result<&mut i64, i64> = Ok(&mut value);
let y: Result<i64, i64> = x.cloned();
//
let mut value = "Foo".to_string();
let x: Result<&mut String, i64> = Ok(&mut value);
let y: Result<String, i64> = x.cloned();