1
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?

More than 3 years have passed since last update.

Result型のfilter_map時にハマった

Last updated at Posted at 2022-03-02

環境

  • rust 1.58.1

やりたかったこと

Vec<Result<Hoge>>型があったとして(Hogeは適当なstruct)、Hogeだけ取得したかった。
以下ではHogeはStringにしています。

// こんなデータがあるとして
let v: Vec<String> = vec!["1".to_string(),"2".to_string(),"3".to_string()];
let string_results = v.into_iter()
    .map(|x| Ok(x))
    .collect::<Vec<Result<String, String>>>();

// Vec<Result<String, String>> からVec<String>をつくりたい!

ハマったこと

let v: Vec<String> = vec!["1".to_string(),"2".to_string(),"3".to_string()];
let string_results = v.into_iter()
    .map(|x| Ok(x))
    .collect::<Vec<Result<String, String>>>();

// これでいけんじゃね?
let inners: Vec<String> = string_results.iter().filter_map(|x| x.ok()).collect();

cannot move out of `*x` which is behind a shared reference
move occurs because `*x` has type `Result<String, String>`, which does not implement the `Copy` traitrustcE0507
main.rs(25, 61): consider borrowing the `Result`'s content: `.as_ref()`

というエラーになってしまってうまくいかない。ok()はselfを消費するからっぽい。

解決方法1

所有権を使ってよいなら、into_iter()を使えば大丈夫

// Vec<Result<String, String>> からVec<String>をつくりたい!
// iter -> into_iterに変更
let inners: Vec<String> = string_results.into_iter().filter_map(|x| x.ok()).collect();

ただし、これだとstring_resultsの所有権が消費されてしまうため、string_resultsをもう使えなくなってしまう。

解決方法2

所有権を消費せずにこれを行うには、上にメッセージででてたas_ref()を使う

// Vec<Result<String, String>> からVec<String>をつくりたい!
// as_ref().ok()にして、中身を参照型で取り出す
let inners: Vec<String> = string_results.iter().filter_map(|x| x.as_ref().ok())
                                   // .map(|x| x.clone()) // 実態にするのは別mapで
                                   .cloned() // 2022-03-06: benki様からご教示いただき、clonedに修正しました。
                                   .collect();

備考

  • なんかもっときれいな方法とかスッキリやる方法あるのではないかという気がする。。
1
0
2

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
1
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?