タプルのVec
のフィールドを含むEnclosingObject
という構造体があります。空白で区切られた文字列を異なるタイプのタプルのVecに慣用的に解析する
これは私がこれまでの(無効の場合は無視して出ているものです... <number of tuples> <tuple1 str1> <tuple1 str2> <tuple1 i32> <tuple2 str1> <tuple2 str2>
:私はEnclosingObject
は、以下の構造を持つ文字列から解析することが可能な方法で、この構造体のFromStr
を実装したいですタプルの数):
use std::str::FromStr;
use std::num::ParseIntError;
#[derive(Debug)]
struct EnclosingObject{
tuples: Vec<(String, String, i32)>,
}
impl FromStr for EnclosingObject {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let elems_vec = s.split_whitespace().collect::<Vec<_>>();
let mut elems = elems_vec.as_slice();
let num_tuples = elems[0].parse::<usize>()?;
elems = &elems[1..];
let mut tuples = Vec::with_capacity(num_tuples);
for chunk in elems.chunks(3).take(num_tuples){
tuples.push((chunk[0].into(),
chunk[1].into(),
chunk[2].parse::<i32>()?));
}
Ok(EnclosingObject{
tuples : tuples
})
}
}
fn main(){
println!("{:?}", EnclosingObject::from_str("3 a b 42 c d 32 e f 50"));
}
それはプリントアウトし、有効な文字列のため、予想通り:
Ok(EnclosingObject { tuples: [("a", "b", 42), ("c", "d", 32), ("e", "f", 50)] })
などの無効な文字列の場合。 "50 F 3 BのXはD = 32 E":
Err(ParseIntError { kind: InvalidDigit })
私はこのようなイテレータを使用するなど、より洗練/慣用の方法でタプルのこのVec
を解析することはできますか?
私はmap
とcollect
の組み合わせを試してみましたが、これに伴う問題は、エラー処理です:
let tuples = elems
.chunks(3)
.take(num_tuples)
.map(|chunk| (chunk[0].into(),
chunk[1].into(),
chunk[2].parse::<i32>()?))
.collect();
questionmark-オペレータは(タプル内の)このような状況では動作しないようです。だから私はそれをちょっと変えました:
let tuples = try!(elems
.chunks(3)
.take(num_tuples)
.map(|chunk| {
let integer = chunk[2].parse::<i32>()?;
Ok((chunk[0].into(),
chunk[1].into(),
integer))})
.collect());
...もう少し面倒です。
作業コードがあることを考慮すると、この質問は[Code Review SE](// codereview.stackexchange.com)に適しているかもしれません。 –
[可能なアプローチ](https://play.rust-lang.org/?gist=de697ed924eba97b96e8e705b31ca8b2&version=stable)個人的には、あなたのバージョン(ループ付き)が好きです。関数型のコードを書くことができますから* – trentcl