75761


文字列の集合`["1", "xxx", "3"]`を順に数字に`parse::<i32>`していき  
変換が **最後まで完遂** できたら、 **最後のパース結果** を返し  
途中で **一度でもパースに失敗したら** エラーを返すような関数`parse_and_last`を作りたいです。

その際、一度パースに失敗した場合、以降のパースは **行わないようにしたい** です。

私の書いたコードは以下になりますが、途中でVecを作成してしまっています。  
これを`Iter`メソッドのみで行う方法は存在するでしょうか？

[code]

    use std::num::ParseIntError;
    
    fn main() {
        let v_ok: Vec<&str> = vec!["1", "2", "3"];
        println!("{:?}", parse_and_last(&v_ok)); // => Ok(3)
    
        let v_err: Vec<&str> = vec!["1", "xxx", "3"];
        println!("{:?}", parse_and_last(&v_err)); // => Err(ParseIntError { kind: InvalidDigit })
    }
    
    fn parse_and_last(v: &[&str]) -> Result<i32, ParseIntError> {
        let results: Result<Vec<i32>, _> = v
            .iter()
            .map(|s| s.parse::<i32>().map(|s| s))
            .collect::<Result<Vec<i32>, _>>();
    
        results.map(|v: Vec<i32>| (*v.last().unwrap()))
    }
    
[/code]


CC BY-SA 4.0
2021-05-10T10:40:06.960
75760
2021-05-10T11:19:49.297
45219
question
rust
Resultを返すようなiterでのエラーハンドリングについて


Rust 1.27.0から導入された `try_fold` を使うとできます。（[ドキュメント](https://doc.rust-
lang.org/stable/std/iter/trait.Iterator.html#method.try_fold)）

[code]

    fn parse_and_last(v: &[&str]) -> Result<i32, ParseIntError> {
        // vが空ではないことを確認する
        // これがないとvが空のときにtry_foldの初期値0が使われ、Ok(0)が返ってしまう
        assert!(!v.is_empty());
    
        // Errが返るまでパースを続ける。Errがなかったときは最後のOkが返る
        v.iter().try_fold(0, |_acc, s| s.parse())
    }
    
[/code]


CC BY-SA 4.0
2021-05-10T11:19:49.297
75761
2021-05-10T11:19:49.297
14101
75760
answer