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();
广告
将在 10 秒后关闭
bannerAds