मेरे पास एक ऐसा फ़ंक्शन है जो Result<Option<[type]>> को Input प्रकार पर लौटाता है:

pub struct Input {
    a: Option<i32>,
    b: Option<i32>,
    c: Option<i32>,
}

input में प्रत्येक फ़ील्ड के लिए यदि मान None है, तो फ़ंक्शन तुरंत Ok(None) वापस आ जाएगा और यदि कोई मान है, तो फ़ंक्शन इसे खोल देगा और आगे तर्क के साथ आगे बढ़ेगा:

fn process(input: Input) -> std::io::Result<Option<i32>> {
    let a = match input.a {
        Some(a) => a,
        None => return Ok(None),
    };
    // the same for b and c...
    todo!()
}

इनपुट प्रकार में सभी क्षेत्रों के लिए दोहराए गए समान पैटर्न। क्या इसे व्यक्त करने का कोई सुंदर तरीका है?

3
Nasif Imtiaz Ohi 6 जुलाई 2021, 18:49

2 जवाब

रात के समय, आप try_blocks का उपयोग कर सकते हैं :

#![feature(try_blocks)]

let x: Option<_> = try { (input.a?, input.b?, input.c?) };

let (a, b, c) = match x {
    Some((a, b, c)) => (a, b, c),
    None => return Ok(None),
};

एक स्थिर विकल्प बना रहा है और तुरंत बंद कर रहा है, हालांकि यह उतना अच्छा नहीं दिखता है:

let x = (|| { Some((input.a?, input.b?, input.c?)) })();

let (a, b, c) = match x {
    Some((a, b, c)) => (a, b, c),
    None => return Ok(None),
};

शायद सबसे साफ समाधान Option::and_then ? ऑपरेटर के साथ संयुक्त:

let x = input.a.and_then(|a| Some((a, input.b?, input.c?)));

let (a, b, c) = match x {
    Some((a, b, c)) => (a, b, c),
    None => return Ok(None),
};

आप Option::zip, हालांकि आप नेस्टेड टुपल्स के साथ समाप्त हो जाएंगे:

let x = input.a.zip(input.b).zip(input.c);

let (a, b, c) = match x {
    Some(((a, b), c)) => (a, b, c),
    None => return Ok(None),
};
2
Ibraheem Ahmed 6 जुलाई 2021, 17:19

एक और संभावना (लेकिन @ sk_pleasant का संस्करण रास्ता साफ है)। खेल का मैदान

fn main() {
    let inp = Input { a:Some(1), b:Some(2), c:Some(3) };
    let unwrapped = 
        inp.a.map_or(None, |a| 
            inp.b.map_or(None, |b| 
                inp.c.map_or(None, |c| Some((a, b, c)))));   
    match unwrapped {
        Some((a, b, c)) => println!("{} {} {}", a, b, c),
        None => println!("None"), // return Ok(None);
    }
}
1
Alexey Larionov 6 जुलाई 2021, 16:18