Rust: `ops::Try` (`try_trait` рд╕реБрд╡рд┐рдзрд╛) рдХреЗ рд▓рд┐рдП рдЯреНрд░реИрдХрд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛

рдХреЛ рдирд┐рд░реНрдорд┐рдд 31 рдордИ 2017  ┬╖  99рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: rust-lang/rust

https://github.com/rust-lang/rfcs/pull/1859 рд╕реЗ Try рд╡рд┐рд╢реЗрд╖рддрд╛ ; рдкреАрдЖрд░ https://github.com/rust-lang/rust/pull/42275 рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛

рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП https://github.com/rust-lang/rust/issues/31436 рд╕реЗ рдЕрд▓рдЧ

  • [ ] рдЗрд╕реЗ рд╕реНрдерд┐рд░ рдХрд░рдиреЗ рд╕реЗ рд▓реЛрдЧ Iterator::try_fold рд▓рд╛рдЧреВ рдХрд░ рд╕рдХреЗрдВрдЧреЗ

    • [ ] рд╕реНрдерд┐рд░реАрдХрд░рдг рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ, рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП try_fold рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рд▓рд┐рдП PR #ремреиремрежрем рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓реЗрдВ

    • [ ] рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рдбреАрдПрдЬреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдмрд╛рдж рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рдирд╛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдЕрд╕рдВрднрд╡ рд╣реИред (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ fold рдХреЛ try_fold рд╕рдВрджрд░реНрдн рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддрд╛рдХрд┐ рджреЛрдиреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛред)

A-error-handling B-RFC-implemented B-unstable C-tracking-issue Libs-Tracked T-lang T-libs

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ?

рд╕рднреА 99 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдмрд╛рдЗрдХрд╢реЗрдбрд┐рдВрдЧ рдХреЗ рдХреБрдЫ рдЯреБрдХрдбрд╝реЗ:

  • рд╣рдо рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░реЗрд░рдгрд╛ рд╣реИ Error рдХреЗ рдмрдЬрд╛рдп Err ? рдЗрд╕реЗ Err рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдпрд╣ Result : рджреВрд╕рд░реЗ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА Ok рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

  • рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрд▓рдЧ from_error рдФрд░ from_ok рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░реЗрд░рдгрд╛ рд╣реИ, рдПрдХ from_result рдмрдЬрд╛рдп рдЬреЛ into_result рд╕рд╛рде рдЕрдзрд┐рдХ рд╕рдордорд┐рдд рд╣реЛрдЧрд╛ рдЬреЛ рдЕрдиреНрдп рд╣реИ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЖрдзрд╛?

( рдЖрд░рдПрдлрд╕реА рд╕реЗ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдХреЗ рд▓рд┐рдВрдХ рдХрд╛ рдЕрджреНрдпрддрди рд╕рдВрд╕реНрдХрд░рдг )

@glaebhoerl

  • Error рдмрдирд╛рдо Err рдкрд░ https://github.com/rust-lang/rust/issues/33417#issuecomment -269108968 рдФрд░ https:// рдореЗрдВ TryFrom рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИред github.com/rust-lang/rust/pull/40281; рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдирд╛рдо рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ред
  • рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рд╡реЗ рдЕрд▓рдЧ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЙрдкрдпреЛрдЧ рд╣реИрдВ, рдФрд░ рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рджреБрд░реНрд▓рдн рд╣реЛрдЧрд╛ рдХрд┐ рдХрд┐рд╕реА рдХреЗ рдкрд╛рд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ Result рдЬрд┐рд╕реЗ рд╡реЗ T:Try рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдореИрдВ Try::from_ok рдФрд░ Try::from_error рдХреЛ рд╣рдореЗрд╢рд╛ Try::from_result(Ok( рдФрд░ Try::from_result(Err( рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ, рдФрд░ рдореБрдЭреЗ рдореИрдЪ рд▓рд┐рдЦрдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛ рд░рд╣реА рд╣реИред рд╢рд╛рдпрдж рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ into_result Into<Result> рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди "рдХреНрдпрд╛ рдпрд╣ рдкрд╛рд╕ рдпрд╛ рдЕрд╕рдлрд▓ рдерд╛?", рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде Result рдПрдХ рдорд╣рддреНрд╡рд╣реАрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдХреЗ рд░реВрдк рдореЗрдВред (рдореИрдВ рд╕реБрдЭрд╛рд╡ рджреЗрдирд╛ рдпрд╛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ "рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЙрддреНрдкрд╛рджрди-рдореВрд▓реНрдп рдмрдирд╛рдо рдкреНрд░рд╛рд░рдВрднрд┐рдХ-рд╡рд╛рдкрд╕реА рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред) рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рд╡рд╣ from_error ? рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИред throw ), рдЬрдмрдХрд┐ from_ok рд╕рдлрд▓рддрд╛-рд░реИрдкрд┐рдВрдЧ (#41414) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддрд╛ рд╣реИ, рдмрдЬрд╛рдп рдЙрди рджреЛрдиреЛрдВ рдХреЛ рдПрдХ рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд░рдЦрдиреЗ рдХреЗред

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЗрд╕ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдордВрдЪ рд╣реИ, рдЕрдЧрд░ рдпрд╣ рдирд╣реАрдВ рд╣реИ рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░реЗрдВ: рд╕реНрдорд╛рдЗрд▓реА:ред рд╢рд╛рдпрдж рдпрд╣ https://github.com/rust-lang/rfcs/pull/1859 рдкрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛ рдФрд░ рдореИрдВ рдЯрд┐рдкреНрдкрдгреА рдЕрд╡рдзрд┐ рд╕реЗ рдЪреВрдХ рдЧрдпрд╛; рдЙрдлрд╝!


рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдХреНрдпрд╛ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдпрд╛ into_result рдкрджреНрдзрддрд┐ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдХреЛрдИ рдорд╛рдорд▓рд╛ рд╣реИ; рдореЗрд░реЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди рдореЗрдВ Try рдХреБрдЫ рд╣рдж рддрдХ рд▓рдХреНрд╖рдгреЛрдВ рдХреЗ рдпреЛрдЧ рдХреА рддрд░рд╣ рд╣реИ FromResult ( from_error рдФрд░ from_ok ) рдФрд░ IntoResult ( into_result рдпреБрдХреНрдд)

FromResult ? рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде рдЕрддреНрдпрдзрд┐рдХ рдПрд░реНрдЧреЛрдиреЛрдорд┐рдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдирд┐рдХрд╛рд╕ рд╕рдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП рд╣рддреНрдпрд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ IntoResult рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рддрд┐-рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╛ Into<Result> рд░реВрдк рдореЗрдВ рдмрдбрд╝реЗ рдХрд░реАрдиреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ; рдХреНрдпрд╛ рдореБрдЭреЗ рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдЙрджрд╛рд╣рд░рдг рдпрд╛рдж рдЖ рд░рд╣реЗ рд╣реИрдВ?

Try рд╡рд┐рд╢реЗрд╖рддрд╛ RFC рдХреЗ рдмрд╛рдж , expr? рд░реВрдк рдореЗрдВ desugar рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

match expr { // Removed `Try::into_result()` here.
    Ok(v) => v,
    Err(e) => return Try::from_error(From::from(e)),
}

рдореИрдВрдиреЗ рдЬрд┐рди рдкреНрд░реЗрд░рдХ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рд╡реЗ рд╣реИрдВ Future рдФрд░ Option ред

рднрд╡рд┐рд╖реНрдп

рд╣рдо FromResult рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ struct FutureResult: Future рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

impl<T, E> FromResult for FutureResult {
    type Ok = T;
    type Error = E;
    fn from_error(v: Self::Error) -> Self {
        future::err(v)
    }
    fn from_ok(v: Self::Ok) -> Self {
        future::ok(v)
    }
}

? рд▓рд┐рдП рдЙрдЪрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдорд╛рдирддреЗ рд╣реБрдП impl Future рдореВрд▓реНрдпрд╡рд╛рди рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ рдЬрдм Result::Err рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдореИрдВ рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реВрдВ:

fn async_stuff() -> impl Future<V, E> {
    let t = fetch_t();
    t.and_then(|t_val| {
        let u: Result<U, E> = calc(t_val);
        async_2(u?)
    })
}
fn fetch_t() -> impl Future<T, E> {}
fn calc(t: T) -> Result<U,E> {}

рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдореИрдВ рдЖрдЬ рдкрд╣рд▓реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ рдФрд░ Try рдЗрд╕реЗ рдирд╛рдЦреВрди! рд▓реЗрдХрд┐рди рд╣рдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ, рддреЛ рд╡рд░реНрддрдорд╛рди Try рдХреЗ рд▓рд┐рдП Future рд╣реЛрддреА рд╣реИ рдХреЗ рд▓рд┐рдП рд╢рд╛рдпрдж рдХреЛрдИ рд╡рд┐рд╣рд┐рдд рд╡рд┐рдХрд▓реНрдк into_result ; рдпрд╣ рдПрдХ рдмрд╛рд░ рдШрдмрд░рд╛рдиреЗ, рдмреНрд▓реЙрдХ рдХрд░рдиреЗ рдпрд╛ рдорддрджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИред рдпрджрд┐ into_result рдкрд░ Try , рддреЛ рдореИрдВ рдЙрдкрд░реЛрдХреНрдд рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд▓реНрджреА рдирд┐рдХрд╛рд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рдФрд░ рдпрджрд┐ рдореБрдЭреЗ Future рдХреЛ Result рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдФрд░ рддрдм рд╕реЗ рдХреЛрдИ рднреА Try ) рдореИрдВ рдЗрд╕реЗ рдПрдХ рдЙрдкрдпреБрдХреНрдд рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ ( wait рд╡рд┐рдзрд┐ рдХреЛ рдмреНрд▓реЙрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд░реЗрдВ, рдХреБрдЫ poll_once() -> Result<T,E> , рдЖрджрд┐ рдкрд░ рдХреЙрд▓ рдХрд░реЗрдВ)ред

рд╡рд┐рдХрд▓реНрдк

Option рдРрд╕рд╛ рд╣реА рдПрдХ рдорд╛рдорд▓рд╛ рд╣реИред рд╣рдо рд▓рд╛рдЧреВ from_ok , from_err рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рдореЗрдВ рдХреЗ рд░реВрдк рдореЗрдВ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдЖрд░рдПрдлрд╕реА , рдФрд░ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ Option<T> рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Result<T, Missing> рдмрд╕ рдХреЗ рд╕рд╛рде o.ok_or(Missing) рдпрд╛ рдПрдХ рд╕реБрд╡рд┐рдзрд╛ рд╡рд┐рдзрд┐ ok_or_missing ред


рдЙрдореНрдореАрдж рд╣реИ рдХреА рд╡реЛ рдорджрдж рдХрд░рджреЗ!

рдореБрдЭреЗ рдЗрд╕ рд╕рдм рдХреЗ рд▓рд┐рдП рд╢рд╛рдпрдж рдмрд╣реБрдд рджреЗрд░ рд╣реЛ рдЪреБрдХреА рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рд╕рдкреНрддрд╛рд╣ рдХреЗ рдЕрдВрдд рдореЗрдВ рдореЗрд░реЗ рд╕рд╛рде рдпрд╣ рд╣реБрдЖ рдХрд┐ ? рдЙрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдПрдХ рдкреНрд░рд╛рдХреГрддрд┐рдХ рдЕрд░реНрдердкреВрд░реНрдг рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк _success_ рдкрд░ рд╢реЙрд░реНрдЯ-рд╕рд░реНрдХрд┐рдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

fn fun() -> SearchResult<Socks> {
    search_drawer()?;
    search_wardrobe()
}

рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, Try рд▓рдХреНрд╖рдг рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдирд╛рдордХрд░рдг рдлрд┐рдЯ рдирд╣реАрдВ рд╣реИред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ ? рдСрдкрд░реЗрдЯрд░ рдХреЗ рдЕрд░реНрде рдХреЛ рд╡рд┐рд╕реНрддреГрдд рдХрд░реЗрдЧрд╛ред

рд░реЗрдпрд╛рди рдХреЗ рд▓рд┐рдП try_fold рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдореЗрдВ, рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ Consumer::full() рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП Try::is_error(&self) рдЬреИрд╕рд╛ рдХреБрдЫ рдЪрд╛рд╣рд╛ред (рд░реЗрдпрди рдХреЗ рдкрд╛рд╕ рдпрд╣ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрднреЛрдХреНрддрд╛ рдореВрд▓ рд░реВрдк рд╕реЗ рдкреБрд╢-рд╕реНрдЯрд╛рдЗрд▓ рдЗрдЯрд░реЗрдЯрд░ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рднреА рд╢реЙрд░реНрдЯ-рд╕рд░реНрдХрд┐рдЯ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред) рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдореБрдЭреЗ рдордзреНрдпрд╡рд░реНрддреА рдорд╛рдиреЛрдВ рдХреЛ Result<T::Ok, T::Err> рд░реВрдк рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рддрд╛рдХрд┐ рдореИрдВ Result::is_err() рдХреЙрд▓ рдХрд░ рд╕рдХреВрдВред

рд╕реЗ рд╡рд╣рд╛рдБ рдореИрдВ рднреА рдПрдХ рдХреЗ рд▓рд┐рдП рдХрд╛рдордирд╛ рдХреА Try::from_result рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП T рдПрдХ рдЕрдВрдд рдореЗрдВ, рд▓реЗрдХрд┐рди match рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдЪрд┐рддреНрд░рдг T::from_ok рдФрд░ T::from_error _рднреА_рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИред

Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдПрд░реНрдЧреЛрдиреЙрдорд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП from_result рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреА рд╣реИ рдпрджрд┐ from_ok рдФрд░ from_error рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛред рдпрд╛ рдареАрдХ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрддред рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рд╕реЗ рдореБрдЭреЗ рджреЛрдиреЛрдВ рдХреА рдкреЗрд╢рдХрд╢ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдорд▓рд╛ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред

рдЪреВрдВрдХрд┐ рдкреАрдЖрд░ #42275 рдХрд╛ рд╡рд┐рд▓рдп рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕реБрд▓рдЭрд╛ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ?

@skade рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрдХ рдкреНрд░рдХрд╛рд░ рдЬреЛ рднреА рд╢реЙрд░реНрдЯ-рд╕рд░реНрдХрд┐рдЯрд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ LoopState рдХреБрдЫ Iterator рдЖрдВрддрд░рд┐рдХ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реИред рд╢рд╛рдпрдж рдпрд╣ рдЕрдзрд┐рдХ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд╣реЛрдЧрд╛ рдпрджрд┐ Try рдиреЗ рд╕рдлрд▓рддрд╛ рдпрд╛ рдЕрд╕рдлрд▓рддрд╛ рдХреЗ рдмрдЬрд╛рдп "рдЬрд╛рд░реА рд░рдЦрдиреЗ рдпрд╛ рддреЛрдбрд╝рдиреЗ" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреАред

@cuviper рдЬрд┐рд╕ рд╕рдВрд╕реНрдХрд░рдг рдХреА рдореБрдЭреЗ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА рд╡рд╣ рдпрд╛ рддреЛ Ok рдкреНрд░рдХрд╛рд░ рдпрд╛ Error -рдЗрди-рдореВрд▓ рдкреНрд░рдХрд╛рд░ рдерд╛ред рдореИрдВ рдЙрдореНрдореАрдж рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рд╡рд┐рдирд╛рд╢-рдФрд░-рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдмрд╛рдд рд╣реИ рдХрд┐ рдпрд╣ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реЛрдЧрд╛ рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░ рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЛрдВ рдХрд╛ рдПрдХ рд╕рдореВрд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред

@ErichDonGubler рдпрд╣ рдПрдХ рдЯреНрд░реИрдХрд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЬрдм рддрдХ рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдб рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛, рддрдм рддрдХ рдЗрд╕рдХрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдЕрдиреБрднрд╡ рд░рд┐рдкреЛрд░реНрдЯ:

рдореИрдВ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдереЛрдбрд╝рд╛ рдирд┐рд░рд╛рд╢ рд╣реБрдЖ рд╣реВрдВред рдХрдИ рдмрд╛рд░ рдЕрдм рдореБрдЭреЗ рдХрд┐рд╕реА рднреА рдХрд╛рд░рдг рд╕реЗ Result рдкрд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реБрднрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рд░ рдмрд╛рд░ рдореИрдВрдиреЗ рдЕрдВрдд рдореЗрдВ рдХреЗрд╡рд▓ Result рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдШрд╛рд╡ рдХрд┐рдпрд╛ рд╣реИ, рдЬреНрдпрд╛рджрд╛рддрд░ рдЗрд╕рд▓рд┐рдП рдХрд┐ Try рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдкреВрд░реА рддрд░рд╣ рдпрдХреАрди рд╣реИ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рдПрдХ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИ рдпрд╛ рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ!

рдЙрджрд╛рд╣рд░рдг:

рдЪрд╛рдХ рд╡реАрдПрдо рдХреЗ рд▓рд┐рдП рдирдП рд╕реЙрд▓реНрд╡рд░ рдореЗрдВ, рдореИрдВ рдПрдХ рдПрдирдо рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдЬреЛ "рд╕реНрдЯреНрд░реИрдВрдб" рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реЛред рдЗрд╕рдХреА рдЪрд╛рд░ рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рдереАрдВ:

enum StrandFail<T> {
    Success(T),
    NoSolution,
    QuantumExceeded,
    Cycle(Strand, Minimums),
}

рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ ? , рдЬрдм рдЗрд╕ рдПрдирдо рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, "рд╕рдлрд▓рддрд╛" рдХреЛ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдЕрдиреНрдп рд╕рднреА рд╡рд┐рдлрд▓рддрд╛рдУрдВ рдХреЛ рдКрдкрд░ рдХреА рдУрд░ рдкреНрд░рдЪрд╛рд░рд┐рдд рдХрд┐рдпрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ "рдЕрд╡рд╢рд┐рд╖реНрдЯ" рдкреНрд░рдХрд╛рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдХреЗрд╡рд▓ рддреНрд░реБрдЯрд┐ рдорд╛рдорд▓реЛрдВ рдХреЛ рд╕рдорд╛рд╣рд┐рдд рдХрд░рддрд╛ рд╣реИ:

enum StrandFail {
    NoSolution,
    QuantumExceeded,
    Cycle(Strand, Minimums),
}

рд▓реЗрдХрд┐рди рдПрдХ рдмрд╛рд░ рдЬрдм рдореБрдЭреЗ рдпрд╣ рдкреНрд░рдХрд╛рд░ рдорд┐рд▓ рдЧрдпрд╛, рддреЛ рдореИрдВ StrandResult<T> рдПрдХ рдЙрдкрдирд╛рдо рднреА рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВ:

type StrandResult<T> = Result<T, StrandFail>;

рдФрд░ рдпрд╣реА рдореИрдВрдиреЗ рдХрд┐рдпрд╛ред

рдЕрдм, рдпрд╣ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдПрдХ рд╣реА рдПрдирдо рд╣реЛрдиреЗ рд╕реЗ рднреА рдмрджрддрд░ рд╣реЛ - рд▓реЗрдХрд┐рди рдпрд╣ рдереЛрдбрд╝рд╛ рдЕрдЬреАрдм рд▓рдЧрддрд╛ рд╣реИред рдЖрдо рддреМрд░ рдкрд░ рдЬрдм рдореИрдВ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд▓рд┐рдЦрддрд╛ рд╣реВрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ "рдареАрдХ" рдФрд░ "рддреНрд░реБрдЯрд┐" рджреНрд╡рд╛рд░рд╛ "рд╕рдореВрд╣" рдирд╣реАрдВ рдХрд░рддрд╛, рдмрд▓реНрдХрд┐ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ "рдмрд░рд╛рдмрд░" рдХреЗ рд░реВрдк рдореЗрдВ рдмрд╛рдд рдХрд░рддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

    /// Invoked when a strand represents an **answer**. This means
    /// that the strand has no subgoals left. There are two possibilities:
    ///
    /// - the strand may represent an answer we have already found; in
    ///   that case, we can return `StrandFail::NoSolution`, as this
    ///   strand led nowhere of interest.
    /// - the strand may represent a new answer, in which case it is
    ///   added to the table and `Ok` is returned.

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдореИрдВрдиреЗ рдпрд╣ рдирд╣реАрдВ рдХрд╣рд╛ "рд╣рдо Err(StrandFail::NoSolution) рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ Err рдмрд╕ рдЗрд╕ рдХрд╖реНрдЯрдкреНрд░рдж рдЖрд░реНрдЯрд┐рдлреИрдХреНрдЯ рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдореБрдЭреЗ рдЬреЛрдбрд╝рдирд╛ рд╣реИред

(рджреВрд╕рд░реА рдУрд░, рд╡рд░реНрддрдорд╛рди рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд╛рдардХреЛрдВ рдХреЛ рдпрд╣ рдЬрд╛рдирдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреА рдХрд┐ ? рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ Try impl рд╕реЗ рдкрд░рд╛рдорд░реНрд╢ рдХрд┐рдП рдмрд┐рдирд╛ рдХреНрдпрд╛ рд╣реИред)

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд░рд┐рдгрд╛рдо рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рдирд╣реАрдВ рд╣реИ: рд╡рд░реНрддрдорд╛рди Try impl рдЖрдкрдХреЛ ? рдЙрди рдЪреАрдЬреЛрдВ рдкрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИ рдЬреЛ Result рд▓рд┐рдП рдЖрдЗрд╕реЛрдореЙрд░реНрдлрд┐рдХ рд╣реИрдВред рдпрд╣ рдПрдХрд░реВрдкрддрд╛ рдХреЛрдИ рджреБрд░реНрдШрдЯрдирд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдпрд╣ рдЙрди рдЪреАрдЬреЛрдВ рдХреЗ рд╕рд╛рде ? рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрд╖реНрдЯрдкреНрд░рдж рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ "рд╕рд┐рд░реНрдл Result " рдирд╣реАрдВ рд╣реИрдВред (рдЙрд╕ рдмрд╛рдд рдХреЗ рд▓рд┐рдП, рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИ рдХрд┐ рдХреЛ рдЬрдиреНрдо рджреЗрддрд╛ рд╣реИ рд╣реИ NoneError - рдХреГрддреНрд░рд┐рдо рд░реВрдк рд╕реЗ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рдПрдХ рдкреНрд░рдХрд╛рд░ рдПрдХ рдХреЗ "рд╡рд┐рдлрд▓рддрд╛" рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд Option ред)

рдореИрдВ рдпрд╣ рднреА рдиреЛрдЯ рдХрд░реВрдВрдЧрд╛ рдХрд┐, StrandFail рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ From::from рд░реВрдкрд╛рдВрддрд░рдг рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдореБрдЭреЗ рдиреБрдХрд╕рд╛рди рдирд╣реАрдВ рдкрд╣реБрдВрдЪрд╛ рд░рд╣рд╛ рд╣реИред

рдХреНрдпрд╛ рд╕рдВрдмрдВрдзрд┐рдд Try::Error рдкреНрд░рдХрд╛рд░ рдХрднреА рднреА рд╕реАрдзреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ? рдпрд╛ рдпрд╣ рд╕рд┐рд░реНрдл ? рдХреА desugaring рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИ? рдпрджрд┐ рдЙрддреНрддрд░рд╛рд░реНрджреНрдз, рдореБрдЭреЗ рдЗрд╕реЗ "рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд░реВрдк рд╕реЗ" рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рджрд┐рдЦрддреА рд╣реИ - type Error = Option<Option<(Strand, Minimums)>> рдпрд╛ рдЬреЛ рднреА рд╣реЛред ( enum рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ "рд╡рд┐рдлрд▓рддрд╛ рдЖрдзреЗ" рдХреЗ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рд╕рдордХрдХреНрд╖ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ-рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдкреАрдЖрдИ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдХрдо рдкрд░реЗрд╢рд╛рди рд▓рдЧрддрд╛ рд╣реИред)

рдореИрдВ рднреА рдкреАрдЫрд╛ рдирд╣реАрдВ рдХрд░рддрд╛ред рдореИрдВрдиреЗ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЖрдВрддрд░рд┐рдХ рддреНрд░реБрдЯрд┐ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдерд╛ рдФрд░ рдпрд╣ Ok рдФрд░ Error рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд▓рдЧрд╛ред рдЖрдк рдпрд╣рд╛рдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ: https://github.com/kevincox/ecl/blob/8ca7ad2bc4775c5cfc8eb9f4309b2666e5163e02/src/lib.rs#L298 -L308

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдХрд╛рдо рдХреЛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕рд░рд▓ рдкреИрдЯрд░реНрди рд╣реИред

impl std::ops::Try for Value {
    type Ok = Self;
    type Error = Self;

    fn from_ok(v: Self::Ok) -> Self { v }
    fn from_error(v: Self::Error) -> Self { v }
    fn into_result(self) -> Result<Self::Ok, Self::Error> {
        if self.is_ok() { Ok(val) } else { Err(val) }
    }
}

рдпрджрд┐ рдЖрдк рд╕рдлрд▓рддрд╛ рдХреЛ рдЦреЛрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

impl std::ops::Try for StrandFail<T> {
    type Ok = T;
    type Error = Self;

    fn from_ok(v: Self::Ok) -> Self { StrandFail::Success(v) }
    fn from_error(v: Self::Error) -> Self { v }
    fn into_result(self) -> Result<Self::Ok, Self::Error> {
        match self {
            StrandFail::Success(v) => Ok(v),
            other => Err(other),
        }
    }
}

рдПрдХ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдХрд╖реНрдЯрдкреНрд░рдж рд▓рдЧрддрд╛ рд╣реИред рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдореИрдВ Self рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдирд┐рд░рд╛рд▓рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдлрд┐рд░ рдЖрдк ? рдХрд╛ рдЙрдкрдпреЛрдЧ StrandResult рд╕реЗ Result<_, StrandResult> рдЖрджрд┐ рдореЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╢рд╛рдирджрд╛рд░ рдЕрдиреБрднрд╡ рд░рд┐рдкреЛрд░реНрдЯ, @nikomatsakis! рдореИрдВ Try (рджреВрд╕рд░реА рджрд┐рд╢рд╛ рд╕реЗ) рд╕реЗ рднреА рдЕрд╕рдВрддреБрд╖реНрдЯ рд╣реВрдВред

TL/DR : рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ FoldWhile рдХреЛ рдпрд╣ рдЕрдзрд┐рдХрд╛рд░ рдорд┐рд▓ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ Break -vs- Continue рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп ? рд╡реНрдпрд╛рдЦреНрдпрд╛ рдкрд░ рдбрдмрд▓-рдбрд╛рдЙрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕реЗ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВред

рд▓рдВрдмрд╛:

рдореИрдВ "рддреНрд░реБрдЯрд┐" рдХреА рддреБрд▓рдирд╛ рдореЗрдВ "рд╕рдлрд▓рддрд╛" рдХреЗ рдХрд░реАрдм рдХреБрдЫ рдХреЗ рд▓рд┐рдП Err рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд░рд╣рддрд╛ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ ? рдЗрддрдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

  • try_fold рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп position (рдФрд░ рдЕрдиреНрдп рдЗрдЯрд░реЗрдЯрд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛) Result рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдКрдкрд░ рдерд╛ (рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдХреЛ find рдкрд╕рдВрдж рдирд╣реАрдВ рдерд╛ Err ) рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп Break рдФрд░ Continue рд╡реЗрд░рд┐рдПрдВрдЯ рдХреЗ рд╕рд╛рде рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛

  • itertools рдореЗрдВ tree_fold1 рд▓рд┐рдЦрддреЗ рд╕рдордп , рдореИрдВ рдПрдХ рдЕрдЬреАрдм match рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реБрдЖ None рдПрдХ рд╕реЗ "рддреНрд░реБрдЯрд┐" рд╣реИ Iterator::next() , рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдпрд╣ рдПрдХ рд╕реЗ "рд╕рдлрд▓рддрд╛" fold , рдЬрдм рд╕реЗ рддреБрдо рдЕрдВрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдФрд░ рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдХреЗ рдкреНрд░рдЪрд╛рд░ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП ? (рдареАрдХ рд╣реИ, рдЙрд╕ рдХреЛрдб рдореЗрдВ try! рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ

рддреЛ рдЕрдЧрд░ рдФрд░ рдХреБрдЫ рдирд╣реАрдВ, рддреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ Try рд▓рд┐рдП рдЬреЛ рд╡рд┐рд╡рд░рдг рд▓рд┐рдЦрд╛ рд╣реИ рд╡рд╣ рдЧрд▓рдд рд╣реИ, рдФрд░ "рд╕рдлрд▓рддрд╛/рд╡рд┐рдлрд▓рддрд╛ рджреНрд╡рдВрджреНрд╡рд╡рд╛рдж" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдирд╣реАрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рдмрд▓реНрдХрд┐ "рддреНрд░реБрдЯрд┐рдпреЛрдВ" рд╕реЗ рджреВрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рджреВрд╕рд░реА рдмрд╛рдд рдЬреЛ рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛, рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдореЗрдВ Try рд▓рд┐рдП рдХреБрдЫ рдереЛрдбрд╝реЗ-рд╕реЗ-рдкрд╛рдЧрд▓ рдЕрд░реНрдереЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Ordering: Try<Ok = (), Error = GreaterOrLess> , "рдХреЛрд╢рд┐рд╢ рдХрд╛рд░реНрдпреЛрдВ" рдХреЗ рд╕рд╛рде рд╕рдВрдпреБрдХреНрдд рд░реВрдк рд╕реЗ cmp рд▓рд┐рдП struct Foo<T, U> { a: T, b: U } рджреЗ рд╕рдХрддрд╛ рд╣реИ

fn cmp(&self, other: &self) -> Ordering try {
    self.a.cmp(&other.a)?;
    self.b.cmp(&other.b)?;
}

рдореБрдЭреЗ рдЕрднреА рддрдХ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдЪреНрдЫреА рддрд░рд╣ рдХрд╛ рдкрд╛рдЧрд▓ рд╣реИ рдпрд╛ рдмреБрд░рд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ: рд╣рдВрд╕рдирд╛: рдЗрд╕рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рд▓рд╛рд▓рд┐рддреНрдп рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рдмрд╛рд░ рдЪреАрдЬреЗрдВ рдЕрд▓рдЧ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдЕрд▓рдЧ рд╣реИрдВред рдФрд░ рдЗрд╕рдХреЗ рджреЛрдиреЛрдВ рдУрд░ "рд╕рдлрд▓рддрд╛" рдпрд╛ "рддреНрд░реБрдЯрд┐" рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рдирд╛ рдареАрдХ рд╕реЗ рдлрд┐рдЯ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИред

рдореИрдВ рдпрд╣ рднреА рдиреЛрдЯ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬрд╣рд╛рдВ "рддреНрд░реБрдЯрд┐-рд░реВрдкрд╛рдВрддрд░рдг" рд╕рд╣рд╛рдпрдХ рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рдЗрд╕реЗ "рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ? рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ" рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрднреА рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдФрд░ рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреБрдорд╛рди рдЙрджрд╛рд╕реА рдкреИрджрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдРрд╕реА рдЪреАрдЬ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рдкрд░рд┐рдгрд╛рдо рддрдХ рд╕реАрдорд┐рдд рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП (рдпрд╛ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ .map_err(Into::into) рдкрдХреНрд╖ рдореЗрдВ рд╣рдЯрд╛ рджреА рдЧрдИ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╢рд╛рдпрдж рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ)ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдУрд╣, рдФрд░ рдпрд╣ рд╕рдм рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╢рд╛рдпрдж "рдореИрдВ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП Try рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЕрдкрдиреА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд░рд╣рддрд╛ рд╣реВрдВ" рдХрд╛ рдЙрддреНрддрд░ "рдЕрдЪреНрдЫрд╛ рд╣реИ, рдпрд╣ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИ"ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ 2: рдпрд╣ рдКрдкрд░ https://github.com/rust-lang/rust/issues/42327#issuecomment -318923393 рдХреЗ рд╡рд┐рдкрд░реАрдд рдирд╣реАрдВ рд╣реИ

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ 3: рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ https://github.com/rust-lang/rfcs/pull/1859#issuecomment -273985250 рдореЗрдВ рдПрдХ Continue рд╕рдВрд╕реНрдХрд░рдг рднреА рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдореЗрд░реЗ рджреЛ рд╕реЗрдВрдЯ:

рдореБрдЭреЗ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рджреЛ рд▓рдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ @fluffysquirrels рдХрд╛ рд╕реБрдЭрд╛рд╡ рдкрд╕рдВрдж рд╣реИред рдПрдХ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рдХрдирд╡рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рджреВрд╕рд░рд╛ рдкрд░рд┐рдгрд╛рдо рд╕реЗ рдХрдирд╡рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ desugaring рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ into_result рдпрд╛ рд╕рдордХрдХреНрд╖ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╣рдореЗрдВ Option рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ Try рд╕реНрдерд┐рд░ рд╣реЛ рдЧрдпрд╛ рд╣реИред

рдореБрдЭреЗ рдЙрди рдирд╛рдореЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ @scottmcm рдХрд╛ рд╡рд┐рдЪрд╛рд░ рднреА рдкрд╕рдВрдж рд╣реИ рдЬреЛ рддреНрд░реБрдЯрд┐/рдареАрдХ рдХреЗ рдмрдЬрд╛рдп рдмреНрд░реЗрдХ/рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддреЗ рд╣реИрдВред

рдпрд╣рд╛рдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдпрд╣ рдкрд╕рдВрдж рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдкрдврд╝рддрд╛ рд╣реИ:

https://github.com/rust-lang/rust/blob/ab8b961677ac5c74762dea955aa0ff4d7fe4915/src/libcore/iter/iterator.rs#L1738 -L1746

рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕реАрдзреЗ рд▓реВрдк рдЬрд┐рддрдирд╛ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди "рдХреЛрд╢рд┐рд╢ рд╡рд┐рдзрд┐рдпреЛрдВ" рдХреЗ рд╕рд╛рде рдпрд╣ рдХрд░реАрдм рд╣реЛрдЧрд╛:

self.try_for_each(move |x| try { 
    if predicate(&x) { return LoopState::Break(x) } 
}).break_value() 

рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ "рддреНрд░реБрдЯрд┐ рд╢рдмреНрджрд╛рд╡рд▓реА" рд╕рдВрд╕реНрдХрд░рдг рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рднреНрд░рд╛рдордХ рд▓рдЧрддрд╛ рд╣реИ:

self.try_for_each(move |x| { 
    if predicate(&x) { Err(x) } 
    else { Ok(()) } 
}).err() 

рдХреНрдпрд╛ рд╣рдо рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдпрд╣ рд╡рд┐рдлрд▓рддрд╛ рдХреНрд░реЗрдЯ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ From<NoneError> for failure::Error рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рджреЗрдЦреЗрдВ https://github.com/rust-lang-nursery/failure/issues/61
рдпрд╣ рдПрдХ 3 рд▓рд╛рдЗрди рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрд░рдПрдлрд╕реА рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВред

@cowang4 рдореИрдВ рдЕрднреА рдкрд░рд┐рдгрд╛рдо-рдФрд░-рд╡рд┐рдХрд▓реНрдк рдХреЗ рдХрд┐рд╕реА рдФрд░ рдорд┐рд╢реНрд░рдг рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рд╡рд┐рдХрд▓реНрдк рд╡рд╣рд╛рдВ рдЦреБрд▓реЗ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдЕрд╕реНрдерд┐рд░ рд╣реИред рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо Try рдХреЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЛ рдмрджрд▓ рджреЗрдВ рдФрд░ desugar рдХреЛ рдХрд┐рд╕реА рдРрд╕реА рдЪреАрдЬрд╝ рдореЗрдВ рдмрджрд▓ рджреЗрдВ рдЬрд┐рд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ NoneError ...

@scottmcm рдареАрдХ рд╣реИред рддреБрдореНрд╣рд╛рд░реА рдмрд╛рдд рд╕рд╣реА рд╣реИред рдЬрдм рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдлрд╝рдВрдХреНрд╢рди рдХреЛрдИ рдирд╣реАрдВ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рддреЛ рдореБрдЭреЗ рдЕрдВрддрддрдГ рдПрд░ рд▓реМрдЯрдиреЗ рдХреЗ рдкреИрдЯрд░реНрди рдХреЛ рдЪреАрдиреА рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдл рддрд░реАрдХрд╛ рдЪрд╛рд╣рд┐рдПред рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк Try рдЕрд▓рд╛рд╡рд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддреЗ рд╣реЛрдВ? рдЙрджрд╛рд╣рд░рдг:

fn work_with_optional_types(pb: &PathBuf) -> Result<MyStruct, Error> {
    if let Some(filestem) = pb.file_stem() {
        if let Some(filestr) = filestem.to_str() {
            return Ok(MyStruct {
                filename: filestr.to_string()
            });
        }
     }
    Err(_)
}

рдПрдХ рдмрд╛рд░ рдЬрдм рдореБрдЭреЗ рдпрд╣ рдкреНрд░рд╛рдпреЛрдЧрд┐рдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдФрд░ failure рдЯреЛрдХрд░рд╛ рдорд┐рд▓ рдЧрдпрд╛, рддреЛ рдореИрдВ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕ рдУрд░ рдЖрдХрд░реНрд╖рд┐рдд рд╣реБрдЖ:

use failure::Error;
fn work_with_optional_types(pb: &PathBuf) -> Result<MyStruct, Error> {
    Ok({
        title: pb.file_stem?.to_str()?.to_string()
    })
}

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдерд╛, impl Display for NoneError рдХреА рдХрдореА рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдХреМрди рд╕рд╛ _рд▓рдЧрднрдЧ_ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди, рдЕрдЧрд░ рдпрд╣ рд╡рд╣ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдирд╣реАрдВ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдЬрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╢рд╛рдпрдж рдХреЛрдИ рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди / рдореИрдХреНрд░реЛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдкреИрдЯрд░реНрди рдХреЛ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИ:

if option.is_none() {
    return Err(_);
}

@ cowang4 рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк From<NoneError> failure::Error рд▓рд┐рдП рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЬреЛ рдЖрдкрдХреЗ рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ Display ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, opt.ok_or(_)? рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢рд╛рдпрдж рдмреЗрд╣рддрд░ рдЕрднреНрдпрд╛рд╕ рд╣реИ рддрд╛рдХрд┐ рдЖрдк рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╣ рд╕рдХреЗрдВ рдХрд┐ рдпрджрд┐ рд╡рд┐рдХрд▓реНрдк рдХреЛрдИ рдирд╣реАрдВ рд╣реИ рддреЛ рддреНрд░реБрдЯрд┐ рдХреНрдпрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрджрд┐ pb.file_stem рдХреЛрдИ рдирд╣реАрдВ рд╣реИ рддреЛ рдЖрдк рдПрдХ рдЕрд▓рдЧ рддреНрд░реБрдЯрд┐ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдпрджрд┐ to_str() рдХреЛрдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред

@tmccombs рдореИрдВрдиреЗ рдЕрдкрдирд╛ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕реЗ рдЧрд▓рдд рдХрд┐рдпрд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдерд╛:

#[macro_use] extern crate failure_derive;

#[derive(Fail, Debug)]
#[fail(display = "An error occurred.")]
struct SiteError;

impl From<std::option::NoneError> for SiteError {
    fn from(_err: std::option::NoneError) -> Self {
        SiteError
    }
}

fn build_piece(cur_dir: &PathBuf, piece: &PathBuf) -> Result<Piece, SiteError> {
    let title: String = piece
        .file_stem()?
        .to_str()?
        .to_string();
    Ok(Piece {
        title: title,
        url: piece
            .strip_prefix(cur_dir)?
            .to_str()
            .ok_or(err_msg("tostr"))?
            .to_string(),
    })
}

рдФрд░ рдлрд┐рд░ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА ...

error[E0277]: the trait bound `SiteError: std::convert::From<std::path::StripPrefixError>` is not satisfied
   --> src/main.rs:195:14
    |
195 |           url: piece
    |  ______________^
196 | |             .strip_prefix(cur_dir)?
    | |___________________________________^ the trait `std::convert::From<std::path::StripPrefixError>` is not implemented for `SiteError`
    |
    = help: the following implementations were found:
              <SiteError as std::convert::From<std::option::NoneError>>
    = note: required by `std::convert::From::from`

error[E0277]: the trait bound `SiteError: std::convert::From<failure::Error>` is not satisfied
   --> src/main.rs:195:14
    |
195 |           url: piece
    |  ______________^
196 | |             .strip_prefix(cur_dir)?
197 | |             .to_str()
198 | |             .ok_or(err_msg("tostr"))?
    | |_____________________________________^ the trait `std::convert::From<failure::Error>` is not implemented for `SiteError`
    |
    = help: the following implementations were found:
              <SiteError as std::convert::From<std::option::NoneError>>
    = note: required by `std::convert::From::from`

рдареАрдХ рд╣реИ, рдореБрдЭреЗ рдЕрднреА рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдпрд╣ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рдХрд┐ рдЕрдиреНрдп рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░реЛрдВ рд╕реЗ рдореЗрд░реА рддреНрд░реБрдЯрд┐ рдореЗрдВ рдХреИрд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЬрд┐рд╕реЗ рдореИрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реВрдВ:

impl<E: failure::Fail> From<E> for SiteError {
    fn from(_err: E) -> Self {
        SiteError
    }
}

рдирд╣реАрдВ...

error[E0119]: conflicting implementations of trait `std::convert::From<SiteError>` for type `SiteError`:
   --> src/main.rs:183:1
    |
183 | impl<E: failure::Fail> From<E> for SiteError {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `core`:
            - impl<T> std::convert::From<T> for T;

рдареАрдХ рд╣реИ, std::error::Error рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

impl<E: std::error::Error> From<E> for SiteError {
    fn from(_err: E) -> Self {
        SiteError
    }
}

рдпрд╣ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ред рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдореЗрд░реЗ From<NoneError> рд╕рд╛рде рд╡рд┐рд░реЛрдз рдХрд░рддрд╛ рд╣реИ

error[E0119]: conflicting implementations of trait `std::convert::From<std::option::NoneError>` for type `SiteError`:
   --> src/main.rs:181:1
    |
175 | impl From<std::option::NoneError> for SiteError {
    | ----------------------------------------------- first implementation here
...
181 | impl<E: std::error::Error> From<E> for SiteError {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `SiteError`
    |
    = note: upstream crates may add new impl of trait `std::error::Error` for type `std::option::NoneError` in future versions

рдЬреЛ рдЕрдЬреАрдм рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ NoneError рдиреЗ std::error::Error рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдЬрдм рдореИрдВ рдЕрдкрдиреЗ рдЧреИрд░-рд╕рд╛рдорд╛рдиреНрдп impl From<NoneError> рдЯрд┐рдкреНрдкрдгреА рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдореБрдЭреЗ рдорд┐рд▓рддрд╛ рд╣реИ:

error[E0277]: the trait bound `std::option::NoneError: std::error::Error` is not satisfied
   --> src/main.rs:189:25
    |
189 |       let title: String = piece
    |  _________________________^
190 | |         .file_stem()?
    | |_____________________^ the trait `std::error::Error` is not implemented for `std::option::NoneError`
    |
    = note: required because of the requirements on the impl of `std::convert::From<std::option::NoneError>` for `SiteError`
    = note: required by `std::convert::From::from`

рдХреНрдпрд╛ рдореБрдЭреЗ рд╕рднреА From s рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрдиреЗ рд╣реЛрдВрдЧреЗред рдореИрдВ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХрд┐ рд╡рд┐рдлрд▓рддрд╛ рдЯреЛрдХрд░рд╛ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛?

рд╢рд╛рдпрдж рдореБрдЭреЗ option.ok_or() рд╕рд╛рде рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдП

рдХреНрдпрд╛ рдореБрдЭреЗ рд╕рднреА Froms рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИред рдореИрдВ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдХрд┐ рд╡рд┐рдлрд▓рддрд╛ рдЯреЛрдХрд░рд╛ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛?

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╡рд┐рдлрд▓рддрд╛ рдЯреЛрдХрд░рд╛ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭрд╕реЗ рдЧрд▓рддреА рд╣реЛ рд╕рдХрддреА рд╣реИред

рдареАрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд╡рд┐рдлрд▓рддрд╛ рдЯреЛрдХрд░рд╛ рдХреА рдлрд┐рд░ рд╕реЗ рдЬрд╛рдВрдЪ рдХреА, рдФрд░ рдЕрдЧрд░ рдореИрдВ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдФрд░ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рд╕рд╣реА рдкрдврд╝ рд░рд╣рд╛ рд╣реВрдВ, рддреЛ рдЗрд╕реЗ рд╣рдореЗрд╢рд╛ failure::Error рдХреЛ рдЖрдкрдХреЗ Result s рдореЗрдВ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣рд╛рдБ рджреЗрдЦреЗрдВ ред рдФрд░, рдпрд╣ рдЕрдзрд┐рдХрд╛рдВрд╢ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдВрдмрд▓ impl Fail рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ:

impl<E: StdError + Send + Sync + 'static> Fail for E {}

https://github.com/rust-lang-nursery/failure/blob/master/failure-1.X/src/lib.rs#L218

рдФрд░ рдлрд┐рд░ рдПрдХ impl From рддрд╛рдХрд┐ рдпрд╣ Try / ? рдЕрдиреНрдп рддреНрд░реБрдЯрд┐рдпреЛрдВ (рдЬреИрд╕реЗ рдПрд╕рдЯреАрдбреА рд╕реЗ) рдХреЛ рд╡реНрдпрд╛рдкрдХ failure::Error рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдмрджрд▓ рд╕рдХреЗред
rust impl<F: Fail> From<F> for ErrorImpl
https://github.com/rust-lang-nursery/failure/blob/d60e750fa0165e9c5779454f47a6ce5b3aa426a3/failure-1.X/src/error/error_impl.rs#L16

рд▓реЗрдХрд┐рди, рдпрд╣ рд╕рд┐рд░реНрдл рдЗрддрдирд╛ рд╣реИ рдХрд┐ рдЪреВрдВрдХрд┐ рдЗрд╕ рдЬрдВрдЧ рдХреЗ рдореБрджреНрджреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рддреНрд░реБрдЯрд┐, NoneError , рдкреНрд░рдпреЛрдЧрд╛рддреНрдордХ рд╣реИ, рдЗрд╕реЗ рдЕрднреА рддрдХ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ Display рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдФрд░, рд╣рдо рдЗрд╕реЗ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ Option s рдФрд░ Result s рдХреЗ рдмреАрдЪ рдХреА рд░реЗрдЦрд╛ рдХреЛ рдзреБрдВрдзрд▓рд╛ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╕рдм рд╢рд╛рдпрдж рдлрд┐рд░ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдФрд░ рдЕрдВрддрддрдГ рд╣рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрднреА рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЙрди рдбреА-рд╢рдХреНрдХрд░ рддрдХрдиреАрдХреЛрдВ рд╕реЗ рдЪрд┐рдкрдХреЗ рд░рд╣реВрдВрдЧрд╛ рдЬреЛ рдореИрдВрдиреЗ рд╕реАрдЦреА рд╣реИрдВред

рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рд╕рднреА рдХрд╛ рдзрдиреНрдпрд╡рд╛рджред рдореИрдВ рдзреАрд░реЗ-рдзреАрд░реЗ рдЬрдВрдЧ рд╕реАрдЦ рд░рд╣рд╛ рд╣реВрдБ! :рдореБрд╕реНрдХреБрд░рд╛рдУ:

рдореИрдВ рдЙрди рдбреА-рд╢рдХреНрдХрд░ рддрдХрдиреАрдХреЛрдВ рд╕реЗ рдЪрд┐рдкрдХреЗ рд░рд╣реВрдВрдЧрд╛ рдЬреЛ рдореИрдВрдиреЗ рд╕реАрдЦреА рд╣реИрдВред

:+1: рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ .ok_or(...)? рдЬрд╛рдиреЗ рдХрд╛ рд░рд╛рд╕реНрддрд╛ рдмрдирд╛ рд░рд╣реЗрдЧрд╛ (рдпрд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ .ok_or_else(|| ...)? )ред рднрд▓реЗ рд╣реА NoneError _had_ рдПрдХ Display impl, рдпрд╣ рдХреНрдпрд╛ рдХрд╣реЗрдЧрд╛? "рдХреБрдЫ рдирд╣реАрдВ рдерд╛"? рдпрд╣ рдХреЛрдИ рдмрдбрд╝реА рдЧрд▓рддреА рдирд╣реАрдВ рд╣реИ...

рдХрд┐рд╕реА рдареЛрд╕ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдХрд░реАрдм рдЬрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕...

рдореБрдЭреЗ TrySuccess рд╡рд┐рдХрд▓реНрдк рдкрд╕рдВрдж рдЖрдиреЗ рд▓рдЧрд╛ рд╣реИред рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ _nobody_, рдЬрд┐рд╕рдореЗрдВ рдореИрдВ рдЦреБрдж рд╢рд╛рдорд┐рд▓ рдерд╛, рдиреЗ рдЙрд╕реЗ рдореВрд▓ рд░реВрдк рд╕реЗ рдкрд╕рдВрдж рдХрд┐рдпрд╛ - рдпрд╣ RFC рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рднреА рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рд╢реБрдХреНрд░ рд╣реИ рдХрд┐ рдпрд╣ рдЗрддрд┐рд╣рд╛рд╕ рдореЗрдВ рдЬреАрд╡рд┐рдд рд╣реИ: https://github.com/rust-lang/rfcs/blob/f89568b1fe5db4d01c4668e0d334d4a5abb023d8/text/0000-try-trait.md#using -an-рд╕рдВрдмрджреНрдз-рдкреНрд░рдХрд╛рд░-рдлреЙрд░-рдж-рд╕рдлрд▓рддрд╛ -рдореВрд▓реНрдп

рдореБрдЭреЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкрд░ рд╕рдмрд╕реЗ рдмрдбрд╝реА рдЖрдкрддреНрддрд┐ рдЙрдЪрд┐рдд рд╢рд┐рдХрд╛рдпрдд рдереА рдХрд┐ рд╕рд┐рд░реНрдл рдПрдХ рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ ( trait TrySuccess { type Success; } ) рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдкреВрд░реНрдг рдореВрд▓ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЕрдзрд┐рдХ рдереАред рд▓реЗрдХрд┐рди catch try рдмреНрд▓реЙрдХ рдмреИрдХ (https://github.com/rust-lang/rust/issues/41414#issuecomment-373985777) рдУрдХреЗ-рд░реИрдкрд┐рдВрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП (рдЬреИрд╕рд╛ рдХрд┐ RFC рдореЗрдВ рд╣реИ) , рдЕрдЪрд╛рдирдХ рдЗрд╕рдХрд╛ рдПрдХ рд╕реАрдзрд╛ рдФрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЙрдкрдпреЛрдЧ рд╣реЛрддрд╛ рд╣реИ: рдпрд╣ рд╡рд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ рдЬреЛ рдЙрд╕ рд░реИрдкрд┐рдВрдЧ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддреА рд╣реИред " ? рд╕рд╛рде рдорд┐рд▓рдХрд░ рд╣рдореЗрд╢рд╛ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП" рд▓рдХреНрд╖реНрдп рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдо рддреМрд░ рдкрд░ рд╡рд╛рдВрдЫрд┐рдд рдерд╛, рд╡рд┐рд╢реЗрд╖рддрд╛ рдмреЗрд╣рддрд░ рд╡рдЬрди рд░рдЦрддреА рд╣реИред рдХрд╛рдХрднрдЧреМрдбрд╝рд╛:

trait TryContinue {
    type Continue;
    fn from_continue(_: Self::Continue) -> Self;
}

рд╡рд╣ рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░, рдЬреИрд╕рд╛ рдХрд┐ ? рдСрдкрд░реЗрдЯрд░ рд╕реЗ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╡рд╣ рднреА рд╡рд╣ рд╣реИ рдЬрд┐рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдореМрдЬреВрдж рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣ "рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ 'рдЕрд╡рд╢рд┐рд╖реНрдЯ' рдкреНрд░рдХрд╛рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП" рдЭреБрдВрдЭрд▓рд╛рд╣рдЯ рдХреЛ рд╣рд┐рдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдирд┐рдХреЛ рдиреЗ рд╡реНрдпрдХреНрдд рдХрд┐рдпрд╛ рдерд╛ ред рдФрд░ рдпрд╣ () рд╣реЛрдирд╛ рдЙрдЪрд┐рдд рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рд╛рдорд╛рдиреНрдп рднреА рд╣реИ, рдЗрд╕рд▓рд┐рдП NoneError рдЬреИрд╕реА рд╡рд┐рдХреГрддрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдмрд╛рдЗрдХрд╢реЗрдб рдХреЗ рд▓рд┐рдП, "рд╡рд╛рдкрд╕реА" рдПрдХ рдЕрдЪреНрдЫрд╛ рд╢рдмреНрдж рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдРрд╕рд╛ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЖрдк return try рд╡рд┐рдзрд┐ (рдЙрд░реНрдл рдУрдХреЗ-рд░реИрдкрд┐рдВрдЧ) рд╕реЗ return ред return рдЗрд╕рдХреЗ рд▓рд┐рдП рдореЛрдирд╛рдб рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдирд╛рдо рднреА рд╣реИ, iiuc...

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ 2: рдЕрдиреНрдп рд▓рдХреНрд╖рдгреЛрдВ/рд╡рд┐рдзрд┐ рдкрд░ рдореЗрд░реЗ рд╡рд┐рдЪрд╛рд░ рдЕрднреА рддрдХ рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВ, @tmccombsред

@scottmcm рдмрд╕ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╛ рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЛ рд▓рдХреНрд╖рдгреЛрдВ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗ рд░рд╣реЗ рд╣реИрдВ?

trait TryContinue {
  type Continue;
  fn from_continue(_: Self::Continue) -> Self;
}

trait Try<E>: TryContinue {
  fn try(self) -> Result<Self::Continue, E>
}

рдФрд░ x? рдХреЛ рдбрд┐рд╕реБрдЧрд░ рдХрд░рдирд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

x.try() match {
    Ok(c) => c,
   Err(e) => throw e // throw here is just a placeholder for either returning or breaking out of a try block
}

рдФрд░ try { ...; expr} рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ desugar рд╣реЛрдЧрд╛:

{ 
    ...
    TryContinue::from_continue(expr);
}

@scottmcm рдореБрдЭреЗ рднреА рдареАрдХ-рд░реИрдкрд┐рдВрдЧ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╕рдордп рд╡рд╣ рд╕рдВрд╕реНрдХрд░рдг рдЕрдзрд┐рдХ рдЖрдХрд░реНрд╖рдХ рд▓рдЧрддрд╛ рд╣реИ =)

рдЕрдЧрд▓реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реБрдП, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ ? рдпрд╣ рдмрди рдЬрд╛рддрд╛ рд╣реИ (рдореЙрдбреНрдпреВрд▓реЛ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдмрд╛рдЗрдХрд┐рдВрдЧ):

trait Try<Other: TryContinue = Self>: TryContinue + Sized {
    fn check(x: Other) -> ControlFlow<Other::Continue, Self>;
}

enum ControlFlow<C, B> {
    Continue(C),
    Break(B),
}

рдорд┐рд╢реНрд░рд┐рдд рдФрдЪрд┐рддреНрдп:

  • рдЗрд╕рдХреЗ рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП TryContinue рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рддрд╛рдХрд┐ x? рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣рдореЗрд╢рд╛ рд╕рдорд╛рди рд╣реЛ
  • рдЗрд╕ рдЪреВрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ Self рдХреА рддрд░рд╣ рд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП try_fold рдХрд┐ рдирд┐рд░реАрдХреНрд╖рдг рдФрд░ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП, рддреЛ рдмрд╕ рдХреЗ рд╕рд╛рде рдареАрдХ рдХрд░ рд░рд╣реЗ рд╣реИрдВ T: Try ред
  • рдпрд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ TryContinue рддрдХ рдлреИрд▓реА рд╣реБрдИ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрджрд┐ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░рдХрд╛рд░ рдЕрдкрдиреЗ рд╢рд░реАрд░ рдореЗрдВ ? рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ рдУрдХреЗ-рд░реИрдкрд┐рдВрдЧ рдХрд╛ рднреА рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
  • рдирдпрд╛ рдПрдирдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдЖрдЗрд╕реЛрдореЙрд░реНрдлрд┐рдХ рд╣реИ, рд▓реЗрдХрд┐рди рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ "рддреНрд░реБрдЯрд┐рдпреЛрдВ" рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рд╕реЗ рдмрдЪрддрд╛ рд╣реИ, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рдЕрд░реНрде рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
  • ? рдХрд╛ рддрд░реНрдХ рд╕рд╛рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░ рд╣реИ, рддрд╛рдХрд┐ TryContinue , рдпрд╣ "рдХрд┐рд╕реА рдЪреАрдЬрд╝ рд╕реЗ Self рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ"

try{} / ? рдФрд░ Option , Result , рдФрд░ Ordering рд▓рд┐рдП рдореИрдХреНрд░реЛ рд╕рд╣рд┐рдд рдкреВрд░реНрдг рдкреНрд░реВрдл-рдСрдл-рдХреЙрдиреНрд╕реЗрдкреНрдЯ рдбреЗрдореЛ: https ://play.rust-lang.org/?gist=18663b73b6f35870d20fd172643a4f96&version=stable (рдзрдиреНрдпрд╡рд╛рдж @nikomatsakis рдПрдХ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рдЗрдирдореЗрдВ рд╕реЗ рдореВрд▓ рдмрдирд╛рдиреЗ

рдбрд╛рдЙрдирд╕рд╛рдЗрдбреНрд╕:

  • рдЕрднреА рднреА Result рдореЗрдВ рдкреНрд░реЗрдд рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ рдЬреЛ рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИрдВ

    • рд▓реЗрдХрд┐рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ Ordering impl рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд LessOrGreater рдкреНрд░рдХрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЯреНрд░реЗрдбрдСрдлрд╝ рд╣реИред

    • рдФрд░ рдЗрдореНрдкреНрд▓рд╕ рдореЗрдВ рдкреНрд░реЗрдд рдкреНрд░рдХрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╡реИрд╕реЗ рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрдо icky рд╣реИрдВ

  • рдПрдХ рд╕реБрд╕рдВрдЧрдд From рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рджреЗрддрд╛

    • рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ StrandResult рдиреЗ рд╡реИрд╕реЗ рднреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХреА, SearchResult рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдпрд╣ рдЕрдЬреАрдм рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдмреНрд░реЗрдХ рдкрде рд╕рдлрд▓рддрд╛ рдкрде рд╣реИ, рдФрд░ рдпрд╣ рдЕрдВрдд рдореЗрдВ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдиреЗрд╕реНрдЯреЗрдб- ? рд╡реИрд╕реЗ рднреА рдорд╛рдорд▓реЗред

  • рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ throw рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреНрдпрд╛ рд╣реЛрдЧрд╛

    • рдХреЗ рд╡рд┐рд╡рд░рдг рдЦреЛ рджреЗрддрд╛ рд╣реИ рдХреМрди рд╕рд╛ ? рдХреЗ рд░реВрдк рдореЗрдВ Ok(x) => x, Err(r) => throw e.into() рд╣реИ рдХрд┐ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╕рдВрдж

    • рд▓реЗрдХрд┐рди throw; рдХреЛ None ( impl<T> Throw<()> for Option<T> рдЬреИрд╕реЗ рдХреБрдЫ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ) рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рднреА рджреЗ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ throw NoneError; рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ

    • рдФрд░ рдЗрд╕реЗ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╡реИрд╕реЗ рднреА рдЕрдЪреНрдЫрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ throw LessOrGreater::Less _really_ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд╣реЛрддрд╛ред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдкрд┐рдВрдЧ @glaebhoerl , рдЬрд┐рд╕рдХреА рд░рд╛рдп рдореИрдВ рдЗрд╕ рдкрд░ RFC 1859 рдореЗрдВ рдПрдХ рдмрдбрд╝реЗ рднрд╛рдЧреАрджрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд╛рд╣реВрдВрдЧрд╛ред

2 рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: https://github.com/rust-lang/rfcs/pull/1859#issuecomment -287402652 рдХреЗ рдЗрд╕ рдХрдерди рдХреЗ рд▓рд┐рдП cc @colin-kiegel рднреА:

рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЙрдкрд░реЛрдХреНрдд рд▓рдХреНрд╖реНрдпреЛрдВ рдХрд╛ рддреНрдпрд╛рдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдиреНрдпреВрдиреАрдХрд░рдгрд╡рд╛рджрд┐рдпреЛрдВ рдХреЗ рдХреБрдЫ рд▓рд╛рд▓рд┐рддреНрдп рдХреЛ рдЕрдкрдирд╛ рд╕рдХрддрд╛ рд╣реИред

рдореБрдЭреЗ рд╡рд╣ рдкреНрд░рд╕реНрддрд╛рд╡ рдмрд╣реБрдд рдкрд╕рдВрдж рд╣реИред

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдереНрд░реЛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреНрдпрд╛ рд╣реЛрдЧрд╛

рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рд╕реЗ рдереНрд░реЛ рдХреАрд╡рд░реНрдб рдХреЗ рд╕рд╛рдорд╛рди рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░рддреЗ рд╣реБрдП, "рдереНрд░реЛ" рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдореВрд▓реНрдп рдХреЛ рдЙрдЪреНрдЪ рджрд╛рдпрд░реЗ рддрдХ "рдлреЗрдВрдХ" рд░рд╣реЗ рд╣реИрдВред рдкрд╛рдпрдерди рдФрд░ рд╕реНрдХреИрд▓рд╛ рддреНрд░реБрдЯрд┐ рдорд╛рдорд▓реЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд▓рд┐рдП рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕реНрдХреИрд▓рд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЖрдк рдЖрдорддреМрд░ рдкрд░ рд╕реАрдзреЗ рдХреЛрд╢рд┐рд╢/рдкрдХрдбрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ), рдЗрд╕рд▓рд┐рдП рд╕рдлрд▓ рдкрдереЛрдВ рдХреЗ рд▓рд┐рдП рдлреЗрдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред

@tmccombs

рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рд╕реЗ рдереНрд░реЛ рдХреАрд╡рд░реНрдб рдХреЗ рд╕рд╛рдорд╛рди рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░рддреЗ рд╣реБрдП, "рдереНрд░реЛ" рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдореВрд▓реНрдп рдХреЛ рдЙрдЪреНрдЪ рджрд╛рдпрд░реЗ рддрдХ "рдлреЗрдВрдХ" рд░рд╣реЗ рд╣реИрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╕рдорд╛рди рд╕рд╛рдорд╛рди рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИ, рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ "рдЙрдард╛рдирд╛" рдмреЗрд╣рддрд░ рдлрд┐рдЯ рд╣реИ:

рдлреЗрдВрдХрдирд╛ (v): рдХрд┐рд╕реА рд╕реНрдерд╛рди, рд╕реНрдерд┐рддрд┐, рд╕реНрдерд┐рддрд┐ рдЖрджрд┐ рдореЗрдВ рдЬрд╛рдиреЗ рдпрд╛ рдЖрдиреЗ рдХрд╛ рдХрд╛рд░рдг, рдЬреИрд╕реЗ рдХрд┐ рдлреЗрдВрдХрдирд╛:

рдЙрдард╛рдирд╛ (v): рдПрдХ рдЙрдЪреНрдЪ рдкрдж рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП; рдЙрдард╛рдирд╛; рддрд░рдХреНрдХреА

? рдХреЗ рддрд░реНрдХ рдХреЗ рд╕рд╛рде "raise" рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ raise рдХрд╛ рдЕрд░реНрде "рдПрдХрддреНрд░" рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдХреБрдЫ рдЗрд╕ рддрд░рд╣: Ok(v) => v, Err(e) => raise From::from(e) , рдЬрд╣рд╛рдВ raise рдорд┐рд▓рд╛рди рдХрд┐рдП рдЧрдП рдкреИрдЯрд░реНрди рдХреА рдирдХрд▓ рдХрд░рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдкреИрдЯрд░реНрди Err(e) рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдпрд╣ ControlFlow::Break(Err(...)) рд▓рд┐рдП рд╡рд╛рдХреНрдп рд░рдЪрдирд╛рддреНрдордХ рдЬрд╛рджреВ рд╣реИ)ред

рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ "рдЙрдард╛рдирд╛" рдПрдХ рдмреЗрд╣рддрд░ рдлрд┐рдЯ рд╣реИ

рдЕрдЪреНрдЫреА рдмрд╛рдд

@scottmcm

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдереНрд░реЛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреНрдпрд╛ рд╣реЛрдЧрд╛

рдХреНрдпрд╛ рдХреЛрдИ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ from_err(value: Other) ?

рдЕрджреНрдпрддрди: рд╢рд╛рдпрдж рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ Other рдХреА рднреВрдорд┐рдХрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЙрд▓рдЭрди рдореЗрдВ рд╣реВрдВред рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рд╣реИред =)

@nikomatsakis

рдХреНрдпрд╛ рдХреЛрдИ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ from_err(value: Other) ?

рдЦреИрд░, Other рдПрдХ рд╕рдВрдкреВрд░реНрдг ? -рд╕рдХреНрд╖рдо рдкреНрд░рдХрд╛рд░ рд╣реИ (рдЬреИрд╕реЗ Result ), рдЗрд╕рд▓рд┐рдП рдореИрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рдХрд┐ throw Ok(4) рдХрд╛рдо рдХрд░реЗред (рдФрд░ рдХреГрддреНрд░рд┐рдо рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдХреА рд╢реБрд░реВрдЖрдд рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред) рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рд╡рд░реНрддрдорд╛рди рд╡рд┐рдХрд▓реНрдк-рдкрд░рд┐рдгрд╛рдо рдЗрдВрдЯрд░рдСрдк рдЗрд╕рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧрд╛ (рдФрд░ рдЙрд▓рдЯрд╛):

impl<T, F, U> Try<Option<U>> for Result<T, F>
   where F: From<NoneError>
{
    fn check(x: Option<U>) -> ControlFlow<U, Self> {
        match x {
            Some(x) => ControlFlow::Continue(x),
            None => ControlFlow::Break(Err(From::from(NoneError))),
        }
    }
}

throw рд▓рд┐рдП рдореЗрд░рд╛ рд╡рд░реНрддрдорд╛рди рдЭреБрдХрд╛рд╡ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣реЛрдЧрд╛:

trait TryBreak<T> : TryContinue { from_break(_: T) -> Self }

рд╕рд╛рде

throw $expr  ==>  break 'closest_catch TryBreak::from_break($expr)
  • TryContinue рдмрдврд╝рд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдУрдХреЗ-рд░реИрдкрд┐рдВрдЧ рдЙрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЬрд┐рд╕рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
  • рдПрдХ рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИ, TryBreak<TryFromIntError> рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ рддреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП TryBreak<io::Error> рджреЛрдиреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

    • рдФрд░ impl<T> TryBreak<()> for Option<T> рд╕рд┐рд░реНрдл throw; impl<T> TryBreak<()> for Option<T> рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░рд╣ рд╕реЗ рдкреНрд░рд╢рдВрд╕рдиреАрдп рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рд╕рдВрдмрджреНрдз рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ () рдирд╣реАрдВ рдерд╛ред

    • impl<T> TryBreak<!> for T рднреА рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдЕрд╕рдВрдЧрдд рд╣реИред

(рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛: рдпреЗ рд╡рд┐рд╢реЗрд╖рддрд╛ рдФрд░ рд╡рд┐рдзрд┐ рдирд╛рдо рднрдпрд╛рдирдХ рд╣реИрдВ; рдХреГрдкрдпрд╛ рдорджрдж рдХрд░реЗрдВ !)

рдпрд╣рд╛рдВ рдЙрдард╛рдП рдЧрдП рдЕрдиреНрдп рдореБрджреНрджреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореЗрд░реЗ рд╡рд┐рдЪрд╛рд░ рдЕрднреА рддрдХ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдЖрдП рд╣реИрдВ, рд▓реЗрдХрд┐рди From::from() desugaring рдХреЗ рдЖрд╕рдкрд╛рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЕрдиреБрдорд╛рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ (рдореБрдЭреЗ рдпрд╛рдж рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рдкрд░ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдХрд╣реАрдВ рдФрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рдереА) , рдпрд╛ рдХреЗрд╡рд▓ рдпрд╣рд╛рдБ?):

рд╕рд╣рдЬ рдЬреНрдЮрд╛рди (рд╣рд╛рд╕реНрдХреЗрд▓ рдЕрдиреБрднрд╡ рд╕реЗ) рдХрд┐ "рдЗрд╕ рддрд░рд╣ рдЭреВрда рдкреНрд░рдХрд╛рд░ рдЕрдиреБрдорд╛рди рдЕрд╕реНрдкрд╖реНрдЯрддрд╛" рдПрдХ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЦреНрдп рдирд╣реАрдВ) рдХрд╛рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдерд╛ рдХрд┐ рдореИрдВ рдореВрд▓ рдЖрд░рдПрдлрд╕реА рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ From рд░реВрдкрд╛рдВрддрд░рдг рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдЕрдм рдЬрдм рдпрд╣ рдХреЗрдХ рдореЗрдВ рдмреЗрдХ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рдЙрд╕ рдХреЗрдХ рдХреЛ рд░рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ 'рд╕рд┐рд░реНрдл' рдЯрд╛рдЗрдк рдХрд░рдХреЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдирд┐рдпрдо рдЬреЛрдбрд╝рдХрд░ рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ?

рдпрд╣реА рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ: рдЬрдм рднреА рд╣рдо рдПрдХ From::from() [рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ: рдПрдХ рдЬреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдХреЗ рдмрдЬрд╛рдп ? desugaring рджреНрд╡рд╛рд░рд╛ рдбрд╛рд▓рд╛ рдЧрдпрд╛ рдерд╛], рдФрд░ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдЬрд╛рдирддреЗ рд╣реИрдВ (рдЗрдирдкреБрдЯ рдмрдирд╛рдо рдЖрдЙрдЯрдкреБрдЯ), рдЬрдмрдХрд┐ рджреВрд╕рд░рд╛ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реИ, рд╣рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рджреВрд╕рд░реЗ рдХреЛ рдПрдХ рдЬреИрд╕рд╛ рд╣реА рдорд╛рдирддреЗ рд╣реИрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдЬрдм рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХрд┐рд╕ impl From рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рддреЛ рд╣рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ impl<T> From<T> for T ред рдпрд╣, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдореВрд▓ рд░реВрдк рд╕реЗ рд╣рдореЗрд╢рд╛ рд╡рд╣реА рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдпрд╣ рд╢рд╛рдпрдж рдереЛрдбрд╝рд╛ рддрджрд░реНрде рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рддреЛ рд▓рд╛рдн IMHO рдХреА рд▓рд╛рдЧрдд рдХреЗ рд▓рд╛рдпрдХ рд▓рдЧрддреЗ рд╣реИрдВред

(рдореИрдВрдиреЗ рдпрд╣ рднреА рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ From рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд▓реИрдВрдЧ рдЖрдЗрдЯрдо рдерд╛, рдареАрдХ ? рдбрд┐рд╕реБрдЧрд░рд┐рдВрдЧ рдХреЗ рдХрд╛рд░рдг, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдкреНрд░рддреАрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ? рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рдорд╛рдпрдиреЛрдВ рдореЗрдВ рдЙрд╕ рдХрд╛рд░рдг рд╕реЗ рд╡рд┐рд╢реЗрд╖ рд╣реИ ред)

@scottmcm рдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ, From::from() desugaring рдХрд╛ _not_ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдпрд╣ Try рд▓рд┐рдП Result рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рд╣реИред

@tmccombs рдореИрдВ рдЙрдирдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдореЗрдВ рд╕рдВрд╢реЛрдзрди рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдирд╣реАрдВ рджреЗ рд░рд╣рд╛ рдерд╛ред

try{} RFC (https://github.com/rust-lang/rfcs/pull/2388) try рдмреНрд▓реЙрдХ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬрд╣рд╛рдВ рдХреЛрдИ рдкрд░рд┐рдгрд╛рдо рдХреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рдХрд▓реНрдк рд╢рд╛рд▓реАрдирддрд╛ рд╕реЗ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪреБрди рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рд╡рд╣ рдЪрд╛рд╣реЗрдВ, рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ

let IgnoreErrors = try {
    error()?;
    none()?;
};

рдкрд╣рд▓реЗ рдХреЗ рд╕рдорд╛рди рд▓рдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдкреНрд░реВрдл-рдСрдл-рдХреЙрдиреНрд╕реЗрдкреНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди: https://play.rust-lang.org/?gist=e0f6677632e0a9941ed1a67ca9ae9c98&version=stable

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд╣рд╛рдВ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рд╕рдВрднрд╛рд╡рдирд╛рдПрдВ рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╕реЗ рдПрдХ рдХрд╕реНрдЯрдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╣ рд╕рдХрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдкрд░рд┐рдгрд╛рдо рд▓реЗ рд╕рдХрддрд╛ рд╣реИ рдФрд░ E: Debug рдмрд╛рдзреНрдп рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреЛ рд▓реЙрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд░рд╛рджрд╛ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ main рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ Termination рд╣реИ рдХрд┐ "рд╕рд┐рд░реНрдл рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ" рдЖрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рджреЗрдиреЗ ? рдЬрдЯрд┐рд▓ рдкреНрд░рдХрд╛рд░ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдмрд┐рдирд╛ (https ://github.com/rust-lang/rfcs/issues/2367)ред

рдореЗрд░реЗ рдкрд╛рд╕ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдореБрджреНрджреЗ рд╣реИрдВ рдЬреЛ @nikomatsakis рджреНрд╡рд╛рд░рд╛ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдореМрдЬреВрджрд╛ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рдорд╛рдгрд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ ред рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореБрджреНрджреЛрдВ рдХреЗ рд▓рд┐рдП, https://github.com/SergioBenitez/Rocket/issues/597#issuecomment -381533108 рджреЗрдЦреЗрдВред

@scottmcm рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ рдЗрди рдореБрджреНрджреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╡реЗ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдкреНрд░рддреАрдд рд╣реЛрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдПрдХ рджрд░рд╛рд░ рд▓реА рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЗ рд╕рд╛рде рдЖрдпрд╛:

#[derive(Debug, Copy, Clone)]
enum ControlFlow<C, B> {
    Continue(C),
    Break(B),
}

// Used by `try { }` expansions.
trait FromTry: Try {
    fn from_try(value: Self::Continue) -> Self;
}

// Used by `?`.
trait Try<T = Self>: Sized {
    type Continue;
    fn check(x: T) -> ControlFlow<Self::Continue, Self>;
}

рдореБрдЦреНрдп рдкрд░рд┐рд╡рд░реНрддрди рдпрд╣ рд╣реИ рдХрд┐ Continue рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░ рд╣реИ рдЬреЛ FromTry (рдкрд╣рд▓реЗ TryContinue ) рдХреЗ рд╡рд┐рдкрд░реАрдд рд╣реИред рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рд▓рд╛рдн рдпрд╣ рд╣реИ рдХрд┐ рд╣реИ Try рдХреЗ рд╕реНрд╡рддрдВрддреНрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ FromTry , рдЬреЛ рдореИрдВ рдЕрдзрд┐рдХ рдЖрдо рдХрд╛ рдорд╛рдирдирд╛ рд╣реИ, рдФрд░ рд╣реИ рдХрд┐ рд▓рд╛рдЧреВ рдХрд░рдиреЗ FromTry рд╕рд░рд▓ рд╣реИ рдПрдХ рдмрд╛рд░ Try рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред (рдиреЛрдЯ: рдпрджрд┐ рдпрд╣ рд╡рд╛рдВрдЫрд┐рдд рд╣реИ рдХрд┐ Try рдФрд░ FromTry рдХреЛ рдПрдХ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рд╣рдо рдХреЗрд╡рд▓ from_try рдкрджреНрдзрддрд┐ рдХреЛ Try рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)

рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдкреВрд░рд╛ рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди рджреЗрдЦреЗрдВ Result рдФрд░ Option рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд░реЙрдХреЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ Outcome рдкрд░ рдЗрд╕ рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди ред

рд░рд┐рдкреЛрд░реНрдЯ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, @SergioBenitez! рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди RFC 1859 рдореЗрдВ рдореВрд▓ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдВрд╕реНрдХрд░рдг "рдлреНрд▓рд┐рдк рдж рдЯрд╛рдЗрдк рдкреИрд░рд╛рдореАрдЯрд░" рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ: https://github.com/rust-lang/rfcs/blob/f89568b1fe5db4d01c4668e0d334d4a5abb023d8/text/0000-try-trait.md#unresolved -рдкреНрд░рд╢рди

рд╕рдмрд╕реЗ рдмрдбрд╝реА рдЪреАрдЬ рдЬреЛ рдЦреЛрддреА рд╣реИ рд╡рд╣ рд╕рдВрдкрддреНрддрд┐ рд╣реИ рдЬреЛ typeof(x?) рдХреЗрд╡рд▓ typeof(x) рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред рдЙрд╕ рд╕рдВрдкрддреНрддрд┐ рдХреА рдХрдореА рдореВрд▓ рдХреЗ рд╕рд╛рде рдЪрд┐рдВрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдереА ("рдореБрдЭреЗ рдЗрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рдореЗрдВ рдкрдардиреАрдпрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝реА рдЪрд┐рдВрддрд╛ рд╣реИ" https://github.com/rust-lang/rfcs/pull/1859#issuecomment-279187967) рдФрд░ рдПрдХ рдлрд╛рдпрджрд╛ рдЕрдВрддрд┐рдо рдиреНрдпреВрдиреАрдХрд░рдг рдкреНрд░рд╕реНрддрд╛рд╡ ("рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреА рдХреЗ рд▓рд┐рдП, ? рдареАрдХ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдареАрдХ/рддреНрд░реБрдЯрд┐ рдорд╛рди рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддрд╛ рд╣реИ" https://github.com/rust-lang/rfcs/pull/1859#issuecomment-283104310)ред рдмреЗрд╢рдХ, рдРрд╕реЗ рддрд░реНрдХ рднреА рдереЗ рдЬреЛ рдХрд╣рддреЗ рдереЗ рдХрд┐ рд╕рдВрдкрддреНрддрд┐ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдпрд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рд╕рд╛рд░рд╛рдВрд╢ рдореЗрдВ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ FCP рдпрд╣ рдЕрднреА рднреА рдПрдХ рд▓рд╛рдн рдХреЗ рд░реВрдк рдореЗрдВ рдерд╛ (https://github.com/rust-lang/rfcs/pull/1859#issuecomment -295878466)ред

рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕рдХрд╛ рдпрд╣ рдлрд╛рдпрджрд╛ рд╣реИ рдХрд┐ Try рдХреЛ FromTry рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдирддрд╛ рд╣реВрдВ

рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдЬ from_ok рдХрдо рдЖрдо рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ Try рдФрд░ do catch рдЕрд╕реНрдерд┐рд░ рд╣реИрдВред рдФрд░ рднрд▓реЗ рд╣реА do catch рд╕реНрдерд┐рд░ рдереЗ, рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ ? рд╕реЗ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рдЪреВрдВрдХрд┐ рдРрд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдмреНрд▓реЙрдХ рдореЗрдВ рдПрдХрд╛рдзрд┐рдХ ? s рд╣реЛрддреЗ рд╣реИрдВ)ред

рд╡рд┐рд╢реЗрд╖рддрд╛ рдФрд░ рдЗрд╕рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдп рд╕реЗ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ "рд╡рд╛рд╣рдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдПрдХ 'рдЪрд▓рддреЗ рд░рд╣реЗрдВ' рдореВрд▓реНрдп рд▓рдкреЗрдЯреЗрдВ" ? рдХрд╛ рдПрдХ рдмрд┐рд▓реНрдХреБрд▓ рдЖрд╡рд╢реНрдпрдХ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред рдЖрдЬ рд╢рд╛рдпрдж рд╣реА рдХреЛрдИ рдЙрд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддрд╛ рд╣реИ - рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХреЗрд╡рд▓ Ok(...) рдпрд╛ Some(...) рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ - рд▓реЗрдХрд┐рди рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, try_fold :

https://github.com/rust-lang/rust/blob/8728c7a726f3e8854f5a80b474d1a8bacab10304/src/libcore/iter/iterator.rs#L1478 -L1482

рдпрджрд┐ рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рд╡рд╛рд╣рдХ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рддреЛ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЙрд╕ рд╡рд╛рд╣рдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд░реБрдЪрд┐ рдХрд╛ рдорд╛рди рдбрд╛рд▓рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИред рдФрд░, рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕реЗ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдХреЛрдИ рдХрдард┐рдирд╛рдИ рд╣реИред рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП, рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП, рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реИред

@Centril рдиреЗ рдкрд╣рд▓реЗ рднреА рдмрддрд╛рдпрд╛ рд╣реИ рдХрд┐ "рдХреИрд░рд┐рдпрд░ рдореЗрдВ рдПрдХ рд╕реНрдХреЗрд▓рд░ рд▓рдкреЗрдЯреЗрдВ" рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╕рд░рд▓ рдирд┐рд░реНрдорд╛рдг рднреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рд╛рд╕реНрдХреЗрд▓ рдЗрд╕реЗ Pointed рдЯрд╛рдЗрдкрдХреНрд▓рд╛рд╕ рдХрд╣рддреЗ рд╣реИрдВ , рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рдо рдЗрд╕реЗ _that_ рд░рд╕реНрдЯ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: try { 4 } тЖж vec![4] рджреЗрдирд╛ рдореБрдЭреЗ рдУрд╡рд░рдХрд┐рд▓ рдЬреИрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ .

рдореИрдВ рдПрдХ рдРрд╕реЗ рднрд╡рд┐рд╖реНрдп рдХреА рднреА рдХрд▓реНрдкрдирд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЬрд╣рд╛рдВ async рдлрд╝рдВрдХреНрд╢рди рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдмреНрд▓реЙрдХ рдорд╛рди рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ try рдлрд╝рдВрдХреНрд╢рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдмреНрд▓реЙрдХ рдорд╛рди рдХреЛ рдПрдХ рдЧрд┐рд░рдиреЗ рдпреЛрдЧреНрдп рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВред рд╡рд╣рд╛рдВ, рдлрд┐рд░ рд╕реЗ, TryContinue рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ - рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди ? рдЙрдкрдпреЛрдЧ рднреА рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЕрдЧрд░ рд╣рдореЗрдВ throw рдирд┐рд░реНрдорд╛рдг рдорд┐рд▓рддрд╛ рд╣реИред

рддреЛ рд╡рд╣ рд╕рдм, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдареЛрд╕ рд╕реЗ рдЕрдзрд┐рдХ рджрд╛рд░реНрд╢рдирд┐рдХ рд╣реИред рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рд╣реИ, рдпрд╛ рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рднреА рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рд╕реЛрдЪрддреЗ рд╣реИрдВ: рдереЛрдбрд╝рд╛_рдореБрд╕реНрдХреБрд░рд╛рддреЗ рд╣реБрдП_рдлреЗрд╕:

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ : рдХреНрд╖рдорд╛ рдХрд░реЗрдВ рдпрджрд┐ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдИрдореЗрд▓ рдорд┐рд▓рд╛ рд╣реИ; рдореИрдВрдиреЗ "рдЯрд┐рдкреНрдкрдгреА" рдмрд╣реБрдд рдЬрд▓реНрджреА рдорд╛рд░рд╛ ...

рд╕рдмрд╕реЗ рдмрдбрд╝реА рдЪреАрдЬ рдЬреЛ рдЦреЛрддреА рд╣реИ рд╡рд╣ рд╕рдВрдкрддреНрддрд┐ рд╣реИ рдЬреЛ рдЯрд╛рдЗрдкреЛрдл (рдПрдХреНрд╕?) рдХреЗрд╡рд▓ рдЯрд╛рдЗрдкреЛрдл (рдПрдХреНрд╕) рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред

рдЖрд╣ рд╣рд╛рдБ, рдмрд┐рд▓реНрдХреБрд▓ред рдпрд╣ рдмрд╛рдд рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рдмреЗрд╢рдХ, рдРрд╕реЗ рддрд░реНрдХ рднреА рдереЗ рдЬреЛ рдХрд╣рддреЗ рдереЗ рдХрд┐ рд╕рдВрдкрддреНрддрд┐ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╣реИ рдпрд╛ рдмрд╣реБрдд рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрддрд┐рдо рд╕рд╛рд░рд╛рдВрд╢ рдореЗрдВ рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ FCP рдпрд╣ рдЕрднреА рднреА рдПрдХ рд▓рд╛рдн рдХреЗ рд░реВрдк рдореЗрдВ рдерд╛ (рд░рд╕реНрдЯ-рд▓реИрдВрдЧ/рдЖрд░рдПрдлрд╕реАрдПрд╕#резреорелреп (рдЯрд┐рдкреНрдкрдгреА))ред

рдХреНрдпрд╛ рдХреЛрдИ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬрд╣рд╛рдВ рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ?

рдпрджрд┐ рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рд╡рд╛рд╣рдХ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рддреЛ рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдЙрд╕ рд╡рд╛рд╣рдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд░реБрдЪрд┐ рдХрд╛ рдорд╛рди рдбрд╛рд▓рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИред рдФрд░, рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕реЗ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдХреЛрдИ рдХрдард┐рдирд╛рдИ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдирд┐рд╖реНрдкрдХреНрд╖ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╣реИред рдореИрдВ рд╕рд╣рдордд рд╣реВрдВред

@SergioBenitez https://github.com/rust-lang/rfcs/pull/1859#issuecomment -279187967 рд╕реЗ

рддреЛ рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдкреНрд░рддрд┐рдмрдВрдз рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВ? рдХреНрдпрд╛ рд╕рдлрд▓рддрд╛ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рддреНрд░реБрдЯрд┐ рдорд╛рдорд▓реЗ рдХреЗ рд╕рдВрджрд░реНрдн рдХреЗ рдЕрдЪреНрдЫреЗ рдЙрдкрдпреЛрдЧ рд╣реИрдВ? рдХреНрдпрд╛ рджреБрд░реНрд╡реНрдпрд╡рд╣рд╛рд░ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ?

рдореИрдВ рд╡рд╛рдпрджрд╛ рдореЗрдВ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рд╕реЗ рдХрд╣ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣рд╛рдВ рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рдорд╛рдорд▓реЗ рднреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЖрдк рдЬрд┐рд╕ рдкреЛрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЙрд╕реЗ рджреЛ рддрд░реАрдХреЛрдВ рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХрднреА-рдХрднреА, рд╣рдо NotReady рд╡реИрд░рд┐рдПрдВрдЯ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рдкрд░рд┐рдгрд╛рдо рдорд╛рди рдХреЗ рд╕рд╛рде рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХрднреА-рдХрднреА, рд╣рдо рдХреЗрд╡рд▓ рд░реЗрдбреА рд╡реЗрд░рд┐рдПрдВрдЯ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рдФрд░ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рд╡реЗрд░рд┐рдПрдВрдЯ (рдЬреИрд╕реЗ рдЖрдкрдХреЗ рд╕реНрдХреЗрдЪ рдореЗрдВ) рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдпрджрд┐ рд╣рдо рд╕рдлрд▓рддрд╛ рдкреНрд░рдХрд╛рд░ рдХреЛ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЗрди рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЕрдзрд┐рдХ рдкреНрд░рд╢рдВрд╕рдиреАрдп рд╣реИ, рдФрд░ рдореВрд▓ рд░реВрдк рд╕реЗ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдкрдШрдЯрди рд╡рд╛рдВрдЫрд┐рдд рд╣реИред

рдУрдЯреАрдУрдПрдЪ, рдореБрдЭреЗ рдЗрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдб рдореЗрдВ рдкрдардиреАрдпрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдЪрд┐рдВрддрд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рддреНрд░реБрдЯрд┐ рдШрдЯрдХ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдЧреБрдгрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рднрд┐рдиреНрди рд▓рдЧрддрд╛ рд╣реИ - рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдореВрд▓ рдорд┐рд▓рд╛рди? рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИред

рддреЛ рдХреЛрдИ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ _рджреЛрдиреЛрдВ_ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджреЗрддрд╛ рд╣реИ, рдЬреИрд╕реЗ

trait Try<T,E> {
    fn question(self) -> Either<T, E>;
}

рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдХрд┐ рд╕рднреА рдХреЛ рд╕рдХреНрд╖рдо рдХрд░реЗрдВ

let x: Result<_,_> = blah.poll()?; // early-return if NotReady
let x: Async<_> = blah.poll()?; // early-return if Error
let x: i32 = blah.poll()?; // early-return both NotReady and Errors

рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпреЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ

println!("{}", z?);
z?.method();

рдЪреВрдВрдХрд┐ рдЙрддреНрдкрд╛рджрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рдВрджрд░реНрдн рдирд╣реАрдВ рд╣реИред

рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬреЛрдВ рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛:

fn foo() -> Result<(), Error> {
    // `x` is an Async<i32> because NotReady doesn't fit in Result
    let x = something_that_returns_poll()?;
}
fn bar() -> Poll<(), Error> {
    // `x` is just i32 because we're in a Poll-returning method
    let x = something_that_returns_poll()?;
}

рдореЗрд░реА рд╡реГрддреНрддрд┐ рд╡рд╣рд╛рдБ рд╣реИ рдХрд┐ рдЕрдиреБрдорд╛рди "рдмрд╛рд╣рд░ рдмрд╣ рд░рд╣рд╛ рд╣реИ?" рд╡рд╣рд╛рдБ рдмрд╣реБрдд рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рд╣реИ, рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдпрд╣ "рдмрд╣реБрдд рдЪрд╛рд▓рд╛рдХ" рдмрд╛рд▓реНрдЯреА рдореЗрдВ рд╣реИред

рдЧрдВрднреАрд░ рд░реВрдк рд╕реЗ, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕рдХрд╛ рди рд╣реЛрдирд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рдмрдВрдзрд╛рддреНрдордХ рд╣реИред my_result? рдПрдХ -> Poll рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдлрд▓рддрд╛ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рд╕рдорд╛рди рд╣реИ (рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХреЛрдб рдХреЛ рдПрд╕рд┐рдВрдХ рд╕рдВрджрд░реНрднреЛрдВ рдореЗрдВ рд╕рдорд╛рди рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг) рдФрд░ рддреНрд░реБрдЯрд┐ рд╕рдВрд╕реНрдХрд░рдг рдареАрдХ рднреА рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛрддрд╛ рд╣реИ . рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП ? рдкрд░ рдПрдХ Poll рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ рдХрд┐ рд░рд┐рдЯрд░реНрди рдореЗрдВ Result рдПрдХ рд╡рд┐рд░реЛрдзреА рдкреИрдЯрд░реНрди рдХреА рддрд░рд╣ рд╡реИрд╕реЗ рднреА рд▓рдЧрддрд╛ рд╣реИ, рдХреБрдЫ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП (рдХрд╛рд▓реНрдкрдирд┐рдХ) рдХреА рддрд░рд╣ рд╕рдорд░реНрдкрд┐рдд рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ .wait(): T (рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдмреНрд▓реЙрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдпрд╛ .ready(): Option<T> (рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдореЛрдб рдЪреБрдирдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдпрдж рд╡реИрд╕реЗ рднреА рдмреЗрд╣рддрд░ рд╣реИред

рдпрд╣ "рджрд┐рд▓рдЪрд╕реНрдк" рд╣реИ https://play.rust-lang.org/?gist=d3f2cd403981a631f30eba2c3166c1f4&version=nightly&mode=debug

рдореБрдЭреЗ рдпреЗ рдХреЛрд╢рд┐рд╢ (рдкрдХрдбрд╝реЗрдВ) рдмреНрд▓реЙрдХ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИрдВ, рд╡реЗ рдмрд╣реБрдд рдирдП рд▓реЛрдЧреЛрдВ рдХреЗ рдЕрдиреБрдХреВрд▓ рдирд╣реАрдВ рд▓рдЧрддреЗ рд╣реИрдВред

рдореИрдВ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЬреЛ рдХрдИ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдлреИрд▓рд╛ рд╣реБрдЖ рд▓рдЧрддрд╛ рд╣реИред рдХреНрдпрд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд▓рдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рдореВрд╣ рдХрд╛ рдПрдХ рд╕рд╛рд░рд╛рдВрд╢ рд╣реИ (рдЬреЛ Error рд╕рдВрдмрджреНрдз рдкреНрд░рдХрд╛рд░ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ)?

рдЗрд╕ рдзрд╛рдЧреЗ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдореБрдЭреЗ Try рдХреЛ рддреНрд░реБрдЯрд┐ рд▓рдХреНрд╖рдгреЛрдВ рд╕реЗ рдЕрд▓рдЧ/рдЕрд▓рдЧ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЯрд┐рдкреНрдкрдгреА рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИ - рдХреНрдпрд╛ рдЙрд╕ рд╡рд┐рднрд╛рдЬрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдпреЛрдЬрдирд╛ рд╣реИ?

рдкреНрд░рд╢реНрди рдЪрд┐рд╣реНрди рдкрд░ Result<T, E> рд╕реЗ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ Other<T2, E> рдореЗрдВ рдкрд╛рд░рджрд░реНрд╢реА рд░реВрдкрд╛рдВрддрд░рдг рд╣реЛрдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ - рдпрд╣ рдореМрдЬреВрджрд╛ рдЖрдИрдУ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрдзрд┐рдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП) рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдХреЗ рднреАрддрд░ рд╕реЗ рдЕрдЪреНрдЫреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рд╛рде рдХреЙрд▓ рдХрд░рдиреЗ рджреЗрдЧрд╛ред рдЖрд▓рд╕реА) рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ред

pub fn async_handler() -> AsyncResult<()> {
    let mut file = File::create("foo.txt")?;
    AsyncResult::lazy(move || {
        file.write_all(b"Hello, world!")?;
        AsyncResult::Ok(())
    })
}

рдЕрд░реНрде рдХреА рджреГрд╖реНрдЯрд┐ рд╕реЗ рдпрд╣ From::from(E) -> Other<T2, E> рдЬреИрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди From рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореМрдЬреВрджрд╛ Result -рд╕рдорддреБрд▓реНрдп Try рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рддрдХ рд╕реАрдорд┐рдд рд╣реИред

рдореБрдЭреЗ рд╕рдЪ рдореЗрдВ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ NoneError рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдЯреНрд░реИрдХрд┐рдВрдЧ рд╕рдорд╕реНрдпрд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрднреА рд╕реНрдерд┐рд░ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рддреЛ NoneError рдХреЛ рд╕реНрдерд┐рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ ? рдкрд░ Option рдЕрдзрд┐рдХ рдПрд░реНрдЧреЛрдиреЛрдорд┐рдХ рдмрдирд╛рддрд╛ рд╣реИред struct MyCustomSemanthicalError; рдЬреИрд╕реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдпрд╛ Default рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реА рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред None рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ MyCustomSeemanthicalError рдореЗрдВ From<NoneError> рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

https://github.com/rust-analyzer/rust-analyzer/ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ, рдореБрдЭреЗ ? рдСрдкрд░реЗрдЯрд░ рдореЗрдВ рдЕрдкрд░реНрдпрд╛рдкреНрддрддрд╛ рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рдкреЗрдкрд░рдХрдЯ рдорд┐рд▓рд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ Result<Option<T>, E> ред

рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП, рдпрд╣ ? рд▓рд┐рдП рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ desugar рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ:

match value? {
    None => return Ok(None),
    Some(it)=>it,
}

рдЬрд╣рд╛рдВ value рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╣реИ Result<Option<V>, E> , рдпрд╛:

value?

рдЬрд╣рд╛рдВ value рд╣реИ Result<V, E> ред рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдпрджрд┐ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп Try рдХреЛ Option<T> рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВрдиреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЗ рдореБрджреНрджреЗ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

enum NoneError<E> {
    None,
    Err(E),
}

impl From<T> for NoneError<T> {
    fn from(v: T) -> NoneError<T> {
        NoneError:Err(v)
    }
}

impl<T, E> std::Ops::Try for Result<Option<T>, E> {
    type OK = T;
    type Error = NoneError<E>;
    fn into_result(self) -> Result<Self::OK, Self::Error> {
        match self {
            Ok(option) => {
                if let Some(inner) = option {
                    Ok(inner)
                } else {
                    Err(NoneError::None)
                }
            }
            Err(error) => {
                Err(NoneError::Err(error));
            }
        }
    }
    fn from_error(v: Self::Error) -> Self {
        match v {
            NoneError::Err(error) => Err(error),
            None => Some(None),
        }
    }
    fn from_ok(v: Self::OK) -> Self {
        Ok(Some(v))
    }
}

impl<T> std::Ops::Try for Option<T> {
    type OK = T;
    type Error = NoneError<!>;
    fn into_result(self) -> Result<Self::OK, Self::Error> {
        match self {
            None => Err(NoneError::None),
            Some(v) => Ok(v),
        }
    }
    fn from_error(v: Self::Error) -> Self {
        match v {
            NoneError::None => Some(None),
            _ => unreachable!("Value of type ! obtained"),
        }
    }
    fn from_ok(v: Self::OK) -> Self {
        Ok(v)
    }
}

рдЬрдм @matklad рд╕реЗ рдкреВрдЫрд╛ Try рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдХрд╕реНрдЯрдо рдПрдирдо рдХреНрдпреЛрдВ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрд╛, рдЬрд┐рд╕реЗ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ Cancellable рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛, рддреЛ рдЙрд╕рдиреЗ рдмрддрд╛рдпрд╛ рдХрд┐ std::ops::Try рдЕрд╕реНрдерд┐рд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ rust-analyzer (рд╡рд░реНрддрдорд╛рди рдореЗрдВ) рд╕реНрдерд┐рд░ рдЬрдВрдЧ рдХреЛ рд▓рдХреНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред

https://github.com/rust-lang/rust/issues/31436#issuecomment -441408288 рд╕реЗ рджреЛрдмрд╛рд░рд╛ рдкреЛрд╕реНрдЯ рдХрд░реЗрдВ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдЗрд╕ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЧрд▓рдд рдореБрджреНрджрд╛ рдерд╛:

рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ, рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдЬреАрдпреВрдЖрдИ рдврд╛рдВрдЪреЗ рдореЗрдВ рдХреЙрд▓рдмреИрдХ рд╣реИ - Option рдпрд╛ Result рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдЙрдиреНрд╣реЗрдВ UpdateScreen рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрдЧрд░ рд╕реНрдХреНрд░реАрди рдХреЛ рдврд╛рдВрдЪреЗ рдХреЛ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЕрдХреНрд╕рд░ рдореБрдЭреЗ рд▓реЙрдЧрд┐рдВрдЧ рдХреА рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ (рд╣рд░ рдЫреЛрдЯреА рддреНрд░реБрдЯрд┐ рдкрд░ рд▓реЙрдЧ рдСрди рдХрд░рдирд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдирд╣реАрдВ рд╣реИ) рдФрд░ рддреНрд░реБрдЯрд┐ рд╣реЛрдиреЗ рдкрд░ рдмрд╕ UpdateScreen::DontRedraw рд▓реМрдЯрд╛рдПрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд░реНрддрдорд╛рди ? рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде, рдореБрдЭреЗ рдЗрд╕реЗ рд╣рд░ рд╕рдордп рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛:

let thing = match fs::read(path) {
    Ok(o) => o,
    Err(_) => return UpdateScreen::DontRedraw,
};

рдЪреВрдВрдХрд┐ рдореИрдВ рдХреЛрд╢рд┐рд╢ рдСрдкрд░реЗрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ Result::Err рд╕реЗ UpdateScreen::DontRedraw рдХрдирд╡рд░реНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдпрд╣ рдмрд╣реБрдд рдХрдард┐рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ - рдЕрдХреНрд╕рд░ рдореЗрд░реЗ рдкрд╛рд╕ рд╣реИрд╢ рдореИрдкреНрд╕ рдореЗрдВ рд╕рд░рд▓ рд▓реБрдХрдЕрдк рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд┐рдлрд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдЬреЛ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ ) - рдЕрдХреНрд╕рд░ рдПрдХ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдореЗрд░реЗ рдкрд╛рд╕ ? рдСрдкрд░реЗрдЯрд░ рдХреЗ 5 - 10 рдЙрдкрдпреЛрдЧ рд╣реЛрддреЗ рд╣реИрдВред рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрд░реЛрдХреНрдд рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╣реА рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд╣реИ, рдореЗрд░рд╛ рд╡рд░реНрддрдорд╛рди рд╕рдорд╛рдзрд╛рди impl From<Result<T>> for UpdateScreen рдЗрд╕ рддрд░рд╣ рд╣реИ , рдФрд░ рдлрд┐рд░ рдЗрд╕ рддрд░рд╣ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдПрдХ рдЖрдВрддрд░рд┐рдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

fn callback(data: &mut State) -> UpdateScreen {
     fn callback_inner(data: &mut State) -> Option<()> {
         let file_contents = fs::read_to_string(data.path).ok()?;
         data.loaded_file = Some(file_contents);
         Some(())
     }

    callback_inner(data).into()
}

рдЪреВрдВрдХрд┐ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ -> impl Into<UpdateScreen> рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ (рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЗ рд▓рд┐рдП impl рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИ)ред рддреЛ рдореЗрд░реЗ рд▓рд┐рдП Try рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рдЖрдВрддрд░рд┐рдХ-рдлрд╝рдВрдХреНрд╢рди рдЪрд╛рд▓ рдХрд░рдирд╛ рд╣реИред рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдореИрдВ рдмрд╕ рдРрд╕рд╛ рдХреБрдЫ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ:

impl<T> Try<Result<T>> for UpdateScreen {
    fn try(original: Result<T>) -> Try<T, UpdateScreen> {
        match original {
             Ok(o) => Try::DontReturn(o),
             Err(_) => Try::Return(UpdateScreen::DontRedraw),
        }
    }
}

fn callback(data: &mut State) -> UpdateScreen {
     // On any Result::Err, convert to an UpdateScreeen::DontRedraw and return
     let file_contents = fs::read_to_string(data.path)?;
     data.loaded_file = Some(file_contents);
     UpdateScreen::Redraw
}

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд░реНрддрдорд╛рди рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ рдФрд░ рдореИрдВ рд╕рд┐рд░реНрдл рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧ-рдорд╛рдорд▓реЗ рдХреЛ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдХреЛрдИ рдХрд╕реНрдЯрдо рдЯреНрд░рд╛рдИ рдСрдкрд░реЗрдЯрд░ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░ рд╕рдХреЗред

@joshtriplett рдЗрд╕ рдкрд░ рд╡рд╛рдкрд╕ рдЖрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдордп рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред рдореИрдВрдиреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдпрд╢реАрд▓ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк https://github.com/rust-lang/rust/compare/master...scottmcm :try-trait-v2 рдкрд░ рдареЛрд╕ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рде рд░рдЦрд╛ рд╣реИред рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рдФрд░ рдЪреАрдЬреЛрдВ рдХреЛ рдЖрдЬрдорд╛рдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реВрдВред

@scottmcm рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдХреБрдЫ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рд╡реНрдпрд╛рдЦреНрдпрд╛ рд╣реИ?

@scottmcm FWIW рдореИрдВрдиреЗ рд░реЗрдпрд╛рди рдореЗрдВ рднреА рдЖрдкрдХреЗ рдмрджрд▓рд╛рд╡реЛрдВ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА:
https://github.com/rayon-rs/rayon/compare/master...cuviper :try-trait-v2
(рдЕрднреА рднреА рдЕрд╕реНрдерд┐рд░ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмрдЬрд╛рдп рдирд┐рдЬреА рдкреНрд░рддрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ)

рддреЛ Option noneError рдХреЛ рдХрдиреНрд╡рд░реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдЙрдкрд╛рдп рдХреНрдпрд╛ рд╣реИ? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐, рдХреНрдпреЛрдВрдХрд┐, рдпрд╣ рдЯреНрд░рд╛рдИ рдЯреНрд░реИрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рддрдм рддрдХ рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрдм рддрдХ рдЖрдк рдЙрд╕ рд╡рд┐рд╢реЗрд╖ (рдЕрд╕реНрдерд┐рд░?) рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрддреЗред

рддреЛ рдореВрд▓ рд░реВрдк рд╕реЗ, рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде рдСрдкрд░реЗрдЯрд░ рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореБрдЭреЗ рдкрддрд╛ рд╣реИ?

@omarabid , рдСрдкрд░реЗрдЯрд░ Option рдпрд╛ Result рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рд░ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рд╕реНрдерд┐рд░ рд╣реЛрдиреЗ рддрдХ Try рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрд╛рдзрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред ? рдХреЛ Option рдкрд░ Option рд▓реМрдЯрдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд┐рд▓реНрдХреБрд▓ рдареАрдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХреЛ NoneError рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдпрджрд┐ рдЖрдк рдкреНрд░рдХрд╛рд░ рдорд┐рдЯрд╛рддреЗ рд╣реИрдВ рддреЛ рдЖрдк Result рднреА рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

use std::fmt::Debug;

pub struct Error(Box<dyn Debug>);

impl<T: Debug + 'static> From<T> for Error {
    fn from(error: T) -> Self {
        Error(Box::new(error))
    }
}

pub fn try_get<T>(slice: &[T], index: usize) -> Result<&T, Error> {
    Ok(slice.get(index)?)
}

( рдЦреЗрд▓ рдХрд╛ рдореИрджрд╛рди )

@scottmcm , рдЖрдкрдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк try-trait-v2 рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ!

рдЕрдЧрд░ рд╣рдо рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рдХрд┐ рдореЗрд░рд╛ рдЙрджрд╛рд╣рд░рдг рдЯреВрдЯ рдЬрд╛рдП, рддреЛ try-trait-v2 рдХреЛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:

#[unstable(feature = "try_trait_v2", issue = "42327")]
impl<T, U, E: From<NoneError>> ops::Bubble<Result<U, E>> for Option<T> {
    fn bubble(self) -> ops::ControlFlow<T, Result<U, E>> {
        match self {
            Some(x) => ops::ControlFlow::Continue(x),
            None => ops::ControlFlow::Break(Err(E::from(NoneError))),
        }
    }
}

рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреНрдпрд╛ рд╣реИ?

рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП try_fold рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХреЗ рдкреАрдЖрд░ #62606 рдХреЛ рд╕реНрдерд┐рд░ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдЙрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреНрд░реИрдХрд┐рдВрдЧ рдЖрдЗрдЯрдо рдХреЗ рд╕рд╛рде рд╕реЗрд╢рди рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ ~ scottmcm

рдХреНрдпрд╛ рдЗрд╕ рдереНрд░реЗрдб рдореЗрдВ рд╕реБрдЭрд╛рдП рдЧрдП рдХрд┐рд╕реА рднреА рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдХреЛрдИ рдпреЛрдЬрдирд╛ рд╣реИ? @scottmcm рджреНрд╡рд╛рд░рд╛ рд╕реБрдЭрд╛рдпрд╛ рдЧрдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рдареАрдХ рд▓рдЧрддрд╛ рд╣реИред рдореИрдВ ? рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ Option , рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ Result рд╕реЗрдореЗрдиреНрдЯрд┐рдХреНрд╕ рдХреЛ Option рдкрд░ рдмрд╛рдзреНрдп рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрджрд▓рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

@scottmcm рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд╣рдо ? рд╕рд╛рде Option рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВрдЧреЗ рдФрд░ NoneError рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХреЗрдВрдЧреЗред рдореИрдВ @nikomatsakis ( рдЯрд┐рдкреНрдкрдгреА ) рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ " Option рдХреА 'рд╡рд┐рдлрд▓рддрд╛' рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреГрддреНрд░рд┐рдо рд░реВрдк рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП"ред

pub struct Error(Box<dyn std::fmt::Debug>);
impl<T: std::fmt::Debug + 'static> From<T> for Error { fn from(error : T) -> Self { Error(Box::new(error)) } }
type Result<T> = std::result::Result<T, Error>;

рд╢реБрд░реБрдЖрддреА рдпрд╣рд╛рдБ, рдореИрдВ рдкрд╛рдиреЗ рдХреА рдЪрд╛рд╣рдд рдореЗрдВ рдереЛрдбрд╝рд╛ рдЬрд┐рджреНрджреА рдерд╛? рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдФрд░ рд╡рд┐рдХрд▓реНрдк рджреЛрдиреЛрдВ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдорд┐рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдПред
рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рдордп рдмрд┐рддрд╛рдиреЗ рдХреЗ рдмрд╛рдж рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЕрдиреНрдп рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЛ рдХреНрдпреЛрдВ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рд╣реИ рдХрд┐ @cuviper рдореБрдЭреЗ рдЬреЛ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ рдЙрд╕рдХреЗ рд╕рдмрд╕реЗ рдХрд░реАрдм рд╣реИред
рдХреБрдЫ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдгреЛрдВ рдиреЗ рдорджрдж рдХреА рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо рдореБрдЭреЗ рдХреБрдЫ рд░рд╕реНрдЯ рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕реАрдорд╛рдУрдВ рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдирд╛ рдкрдбрд╝рд╛ред
рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдареЛрд╕ рд╢рдмреНрджреЛрдВ рдореЗрдВ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред
рдпрд╣ рдзрд╛рдЧрд╛ рд╕рдмрд╕реЗ рд╕рдВрднрд╛рд╡рд┐рдд рдЪреМрд░рд╛рд╣реЗ рд▓рдЧрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдореИрдВ рдЙрдореНрдореАрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдореЗрд░реЗ рдЬреИрд╕реЗ рдХрд┐рд╕реА рдХреЛ рднреА рдЗрд╕ рдкрд░ рдареЛрдХрд░ рдЦрд╛рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓ рд╕рдХреЗ, рд╕рд╣реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ:

  • StdError рдХреЗ рдмрдЬрд╛рдп рдбреАрдмрдЧ (StdError рдФрд░ noneError рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:
    рдПрдХ рд╕рд╛рдорд╛рдиреНрдп From<T: StdError> for Error рдФрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ From<NoneError> for Error рд╡рд┐рд░реЛрдз
    рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реЛрдЧрд╛ рдпрджрд┐ рдХреЛрдИ рдирд╣реАрдВ рддреНрд░реБрдЯрд┐ рдиреЗ StdError рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ (рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рднреА рдУрд╡рд░рд░рд╛рдЗрдб рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ рдФрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ)
    рдЗрд╕реЗ "рдирдХрд╛рд░рд╛рддреНрдордХ рдмрд╛рдзреНрдп" рджреНрд╡рд╛рд░рд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ, рд╢рд╛рдпрдж рдЗрд╕рд▓рд┐рдП рдХрд┐ рдпрд╣ рдПрдХрдорд╛рддреНрд░ рдЙрдкрдпреЛрдЧ рдХреЗрд╕ рд╣реЛрдЧрд╛? (рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╕реЗ рдЕрдзрд┐рдХ)
    рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреЗ рд▓рд┐рдП impl StdError рдХреЛ рдХреЗрд╡рд▓ StdError рдпрд╛ noneError рдХреЗ рд╕рд╛рде рд╣реА рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддрд╛рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рднреА рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдореЗрдВ рд╕реБрд╕рдВрдЧрдд рд╣реЛред
  • рддреНрд░реБрдЯрд┐ рдПрдХ рдЙрдкрдирд╛рдо рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА:
    type Error = Box<Debug> рдбрд┐рдмрдЧ рдХреЛ рдмрд╛рдВрдзрддрд╛ рд╣реИ рдЬреЛ From<T:Debug> for Error рдХреЛ From<T> for T рд╕рд╛рде рд╕рдВрдШрд░реНрд╖ рдХрд░рддрд╛ рд╣реИ (рдмреЗрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рд╡рд░реНрдд)

рдЗрд╕рд▓рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рддреНрд░реБрдЯрд┐ рдбреАрдмрдЧ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк рдПрдХ рд╕рд╣рд╛рдпрдХ рдХреЛ рдкрд░рд┐рдгрд╛рдо рдореЗрдВ рдЯреНрд░рд╛рдВрдЬрд┐рдЯрд┐рд╡ рдбреАрдмрдЧ рдХреЗ рд╕рд╛рде рдЦреЛрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:

fn from<T>(result : Result<T>) -> std::result::Result<T, Box<dyn std::fmt::Debug>> { match result { Ok(t) => Ok(t), Err(e) => Err(e.0) } }

рдпрд╣ impl From<Result<T>> for StdResult<T> рдФрд░ рди рд╣реА Into<StdResult> for Result<T> рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдЕрдкрд╕реНрдЯреНрд░реАрдо рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЕрдкрд╕реНрдЯреНрд░реАрдо рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛)

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЯрд░реНрдорд┐рдиреЗрд╢рди рдХреЗ рд▓рд┐рдП рдбреАрдмрдЧ рд░рд┐рдЯрд░реНрди рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

fn main() -> std::result::Result<(), Box<dyn std::fmt::Debug>> { from(run()) }

рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░: рд╢рд╛рдпрдж ? рдСрдкрд░реЗрдЯрд░ рдХрд┐рд╕реА рддрд░рд╣ рдПрдХ рдореЛрдиреИрдбрд┐рдХ рдмрд╛рдЗрдВрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП

let x: i32 = something?;
rest of function body

рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ

Monad::bind(something, fn(x) {
    rest of function body
})

рдПрдХ рднрдпрд╛рдирдХ рд╡рд┐рдЪрд╛рд░, рд▓реЗрдХрд┐рди рдпрд╣ рдореЗрд░реЗ рднреАрддрд░ рдХреЗ рдЧреАрдХ рдХреЛ рдкреНрд░рд╕рдиреНрди рдХрд░рддрд╛ рд╣реИред

@derekdreery рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ return рдФрд░ continue рдЬреИрд╕реЗ рдЕрдирд┐рд╡рд╛рд░реНрдп рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛

рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ ? рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдерд┐рд░ рд╣реИрдВред рдХреЗрд╡рд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдЕрд╕реНрдерд┐рд░ рд╣реИ, рдФрд░ рдХрд┐рд╕реА рднреА рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ Option рдФрд░ Result рд▓рд┐рдП рд╕рдорд╛рди рд╕реНрдерд┐рд░ рдкреНрд░рднрд╛рд╡ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

@рдХреГрд╖реНрдгрд╛рд╕рдирд╕реА

@derekdreery рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рдЕрдирд┐рд╡рд╛рд░реНрдп рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╡рд╛рд╣ рдЬреИрд╕реЗ рд╡рд╛рдкрд╕реА рдФрд░ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд╕рд╛рде рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛

рдореИрдВ рдЗрд╕ рдХрдерди рд╕реЗ рд╕рд╣рдордд рд╣реВрдВред

@рдХреНрдпреВрд╡рд┐рдкрд░

рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рд╢рдмреНрджрд╛рд░реНрде ? рдСрдкрд░реЗрдЯрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдерд┐рд░ рд╣реИрдВред рдХреЗрд╡рд▓ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рдпрд╛рд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЕрд╕реНрдерд┐рд░ рд╣реИ, рдФрд░ рдХрд┐рд╕реА рднреА рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд╡рд┐рдХрд▓реНрдк рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╕реНрдерд┐рд░ рдкреНрд░рднрд╛рд╡ рдмрдирд╛рдП рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХреНрдпрд╛ рдпрд╣ рдпреБрдЧреЛрдВ рдореЗрдВ рднреА рд╕рдЪ рд╣реИ?

рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдиреЛрдЯ рдкрд░, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ .await , ?/ рдЬрд▓реНрджреА рд╡рд╛рдкрд╕реА рдЬреИрд╕реА рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рд╡рд┐рдХрд▓реНрдк :: рдирдХреНрд╢рд╛, рдкрд░рд┐рдгрд╛рдо :: рдирдХреНрд╢рд╛, рдЗрдЯрд░реЗрдЯрд░ :: рдирдХреНрд╢рд╛ рдЬрдВрдЧ рдореЗрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдордЭрддреЗ рд╣реБрдП рдХрд┐ рдпреЗ рд╕рднреА рдХреБрдЫ рд╕рдВрд░рдЪрдирд╛ рд╕рд╛рдЭрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдореБрдЭреЗ рдПрдХ рдмреЗрд╣рддрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдмрдирдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

рдУрдЯреА рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИред

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрдХ рдпреБрдЧ/рд╕рдВрд╕реНрдХрд░рдг рдХреЛ ? desugaring рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рдПрдЧреА, рд▓реЗрдХрд┐рди рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдореИрдХреНрд░реЛрдЬрд╝ рдЬреИрд╕реА рдХрдИ рдХреНрд░реЙрд╕-рдХреНрд░реЗрдЯ рдЪрд┐рдВрддрд╛рдУрдВ рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░реЗрдЧрд╛ред

рд╕реНрдерд┐рд░рддрд╛ рдХреА рдЧрд╛рд░рдВрдЯреА рдФрд░ рдпреБрдЧ RFC рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореЗрд░реА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ ? рд╡реНрдпрд╡рд╣рд╛рд░ (рдЪреАрдиреА рдпрд╛ рдЕрдиреНрдпрдерд╛) рдХреЛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди Option / Result рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдЗрд╕рдХрд╛ рд╡рд░реНрддрдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдмрдирд╛ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдП рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рддреЛрдбрд╝рдиреЗ рд╕реЗ рд╣рдо рдЬрд┐рддрдирд╛ рд╕рд╣реА рдард╣рд░рд╛рдиреЗ рдХреА рдЙрдореНрдореАрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрд╕рд╕реЗ рдХрд╣реАрдВ рдЕрдзрд┐рдХ рдордВрдерди рд╣реЛрдЧрд╛ред

рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ Option рдХрд┐рд╕реА рддрд░рд╣ Result рд▓рд┐рдП рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдирд╛рдо рдерд╛? рдпрд╛рдиреА type Option<T> = Result<T, NoValue> , Option::<T>::Some(x) = Result::<T, NoValue>::Ok(x) , Option::<T>::None = Result::<T, NoValue>::Err(NoValue) ? рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЬрд╛рджреВ рд▓рдЧреЗрдЧрд╛ рдФрд░ рд╡рд░реНрддрдорд╛рди рднрд╛рд╖рд╛ рдХреЗ рдорд╛рд╣реМрд▓ рдореЗрдВ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдпрд╣ рддрд▓рд╛рд╢рдиреЗ рд▓рд╛рдпрдХ рд╣реИред

рд╣рдо рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдХреНрдпреЛрдВрдХрд┐ рдРрд╕реЗ рд▓рдХреНрд╖рдг рд╕рдВрдХреЗрдд рд╣реИрдВ рдЬреЛ Option рдФрд░ Result рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рд╣реЛрдиреЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВред

рдпрджрд┐ рд╣рдо рдЗрд╕реЗ рдЕрдирджреЗрдЦрд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕реЗ рдПрдХ рдХрджрдо рдЖрдЧреЗ рд▓реЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ bool рдХреЛ Result<True, False> рд▓рд┐рдП рдПрдХ рдЙрдкрдирд╛рдо рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ True рдФрд░ False рдЗрдХрд╛рдИ рдкреНрд░рдХрд╛рд░ рд╣реИрдВред

рдХреНрдпрд╛ рдЗрд╕реЗ рдЗрдХрд╛рдИ, () рд▓рд┐рдП Try impl рдЬреЛрдбрд╝рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ? рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рдЧреИрд░-рдорд╣рддреНрд╡рдкреВрд░реНрдг рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рддреНрд░реБрдЯрд┐ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд╛рдкрд╕реА рдЕрднреА рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЬреИрд╕реЗ рд▓реЙрдЧрд┐рдВрдЧ рдХреЙрд▓рдмреИрдХред рдпрд╛, рдЗрдХрд╛рдИ рдХреЛ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЧрдпрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЪреБрдкрдЪрд╛рдк рдЕрдирджреЗрдЦрд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ?

рдпрд╛, рдЗрдХрд╛рдИ рдХреЛ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЧрдпрд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЪреБрдкрдЪрд╛рдк рдЕрдирджреЗрдЦрд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ?

рдЗрд╕ред рдпрджрд┐ рдЖрдк рдЧреИрд░-рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдВрджрд░реНрдн рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЛ unwrap рдпрд╛ рдЗрд╕рдХреЗ рдХрд┐рд╕реА рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ ? рдХреА рддрд░рд╣ рдХреБрдЫ рдкрд░ foo() -> () рдПрдХ рд╕рд╢рд░реНрдд рд╕рдВрдХрд▓рди рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдФрд░ рджреГрдврд╝рддрд╛ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рд╕реЗ рдЕрд▓рдЧ рд╣реИред

рдЖрдкрдХреЛ рдЕрдирд░реИрдк рдпрд╛ рдЗрд╕рдХреЗ рдХрд┐рд╕реА рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

unwrap() рдШрдмрд░рд╛рд╣рдЯ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рдЧреИрд░-рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдВрджрд░реНрднреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ред рдпрд╣ рдЙрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрд╣рд╛рдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд░рд┐рдЯрд░реНрди рд╡рд╛рдВрдЫрд┐рдд рд╣реИред рдХреЛрдИ рдпрд╣ рддрд░реНрдХ рджреЗ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ ? рдХреЗ рд╕реНрдкрд╖реНрдЯ, рджреГрд╢реНрдпрдорд╛рди рдЙрдкрдпреЛрдЧ рдХреЗ рдХрд╛рд░рдг ? рдкреВрд░реА рддрд░рд╣ рд╕реЗ "рдЪреБрдк" рдирд╣реАрдВ рд╣реИред рдЗрд╕ рддрд░рд╣ ? рдФрд░ unwrap() рдпреВрдирд┐рдЯ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИрдВ, рдмрд╕ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд░рд┐рдЯрд░реНрди рд╕реЗрдореЗрдиреНрдЯрд┐рдХреНрд╕ рдХреЗ рд╕рд╛рдеред рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдЬреЛ рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ unwrap() рджреГрд╢реНрдпрдорд╛рди рд╕рд╛рдЗрдб-рдЗрдлреЗрдХреНрдЯреНрд╕ (рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдирд┐рд░рд╕реНрдд/рдПрдХ рд╕реНрдЯреИрдХрдЯреНрд░реЗрд╕ рдкреНрд░рд┐рдВрдЯ рдХрд░реЗрдВ) рдФрд░ ? рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред

рдЕрднреА, рдпреВрдирд┐рдЯ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдореЗрдВ рдЬрд▓реНрджреА рд▓реМрдЯрдиреЗ рдХрд╛ рдПрд░реНрдЧреЛрдиреЙрдорд┐рдХреНрд╕ Result рдпрд╛ Option рд▓реМрдЯрдиреЗ рд╡рд╛рд▓реЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдХрд╛рдлреА рдЦрд░рд╛рдм рд╣реИред рд╢рд╛рдпрдж рдпрд╣ рд╕реНрдерд┐рддрд┐ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЗрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ Result рдпрд╛ Option рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП , рдФрд░ рдпрд╣ рдЙрдирдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдПрдкреАрдЖрдИ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛрддреНрд╕рд╛рд╣рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ, рдкреАрдЖрд░ рдпрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рдпреВрдирд┐рдЯ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреА рдЪрд░реНрдЪрд╛ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдХреНрд╖рдо рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ ? рдХреА рддрд░рд╣ рдХреБрдЫ рдкрд░ foo() -> () рдПрдХ рд╕рд╢рд░реНрдд рд╕рдВрдХрд▓рди рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрд╛рдлреА рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдФрд░ рджреГрдврд╝рддрд╛ рд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рд╕реЗ рдЕрд▓рдЧ рд╣реИред

рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛? рдмрд╕ рд╣рдореЗрд╢рд╛ рдареАрдХ (()) рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░реЗрдВ рдФрд░ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ?

рд╕рд╛рде рд╣реА, рдХреНрдпрд╛ рдЖрдк рдЗрд╕рдХрд╛ рдЙрджрд╛рд╣рд░рдг рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд╣рд╛рдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?

рд╣рд╛рдБ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рдерд╛ рдХрд┐ MyCollection::push рдЬреИрд╕рд╛ рдХреБрдЫ, рд╕рдВрдХрд▓рди рд╕рдордп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╛ рддреЛ рдкрд░рд┐рдгрд╛рдо <(), AllocError> рд╡рд╛рдкрд╕реА рдорд╛рди рдпрд╛ () рд╡рд╛рдкрд╕реА рдорд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рд╕рдВрдЧреНрд░рд╣ рдХреЗрд╡рд▓ рддреНрд░реБрдЯрд┐ рдкрд░ рдШрдмрд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рдВрдЧреНрд░рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рдХреЛрдб рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рд┐рдП, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдпрд╣ рдХреЗрд╡рд▓ _always_ ? рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ () рд╣реЛ рддреЛ рдпрд╣ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ред

рд▓рдЧрднрдЧ 3 рд╡рд░реНрд╖реЛрдВ рдХреЗ рдмрд╛рдж, рдХреНрдпрд╛ рдпрд╣ рд╣рд▓ рд╣реЛрдиреЗ рдХреЗ рдХрд░реАрдм рд╣реИ?

@ рд▓реЛрдХрд╛рдереЛрд░ рдЬреЛ рдХреЗрд╡рд▓ рддрднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдЬрдм рд░рд┐рдЯрд░реНрди рдЯрд╛рдЗрдк Result<Result<X,Y>,Z> рдпрд╛ рдЗрд╕рд╕реЗ рдорд┐рд▓рддрд╛-рдЬреБрд▓рддрд╛ рд╕рдВрднрд╡ рди рд╣реЛред рд▓реЗрдХрд┐рди рдпрд╣ рд╣реИред рдРрд╕реЗ рдореЗрдВ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред

рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рдХреНрдпреЛрдВ рдПрдХ рд╕реНрддрд░рд┐рдд рдкрд░рд┐рдгрд╛рдо рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рд╡рд┐рд╕реНрддреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

рдХреНрд░реЙрд╕- рд░реЗрдлрд░реЗрдВрд╕рд┐рдВрдЧ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП,

https://internals.rust-lang.org/t/a-slightly-more-general-easier-to-implement-alternative-to-the-try-trait/12034

@рд▓реЛрдХрдереЛрд░
рдареАрдХ рд╣реИ, рдореИрдВрдиреЗ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдФрд░ рдЧрд╣рд░рд╛рдИ рд╕реЗ рд╕реЛрдЪрд╛ рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдПрдХ рдЕрдЪреНрдЫреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдорд┐рд▓ рд╕рдХрддреА рд╣реИред

рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдпрд╛ рдЕрдЬреАрдм рдПрдиреЛрдЯреЗрд╢рди рдХреЛрдб рдХреЛ рдЕрд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░ рджреЗрдЧрд╛ред рдпрд╣ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЛрдб рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рдХрдард┐рди рдмрдирд╛ рджреЗрдЧрд╛ред (рдкреВрд░реНрд╡ рд╢рд░реНрдд: #[debug_result] рдЖрдкрдХреЗ рд╡рд╛рдВрдЫрд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ Result::Err(...) рд▓реМрдЯрдиреЗ рдХреЗ рдмрдЬрд╛рдп рд░рд┐рд▓реАрдЬ рдореЛрдб рдореЗрдВ рдШрдмрд░рд╛рд╣рдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ Result::Ok рдЦреЛрд▓рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╣ рд╣рд┐рд╕реНрд╕рд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ)

#[debug_result]
fn f() -> Result<X, Y>;

#[debug_result]
fn f2() -> Result<Result<A, B>, Y>;

#[debug_result]
fn g() -> Result<X, Y> {
    // #[debug_result_spoiled]
    let w = f();
    // w could have type X or `Result<X,Y>` based on a #[cfg(debug_...)]
    // the following line would currently only work half of the time
    // we would modify the behavoir of `?` to a no-op if #[cfg(not(debug_...))]
    // and `w` was marked as `#[debug_result]`-spoiled
    let x = w?;

    // but it gets worse; what's with the following:
    let y = f2();
    let z = y?;
    // it has completely different sematics based on a #[cfg(debug_...)],
    // but would (currently?) print no warnings or errors at all,
    // and the type of z would be differently.

    Ok(z)
}

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣ рдХреЛрдб рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рдХрдард┐рди рдмрдирд╛ рджреЗрдЧрд╛ред
рд╣рдо рдХреЗрд╡рд▓ ? рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдХреЗрд╡рд▓ рдиреЛ-рдСрдк рдореЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ,
рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдпрджрд┐ #[debug_result] рдХрд╛ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдПрдХ рдЕрд╕реНрдерд╛рдпреА рдЪрд░ рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдмрд╛рдж рдореЗрдВ ? рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде "рдХреЛрд╢рд┐рд╢-рдкреНрд░рд╕рд╛рд░" рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ ? рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рднреНрд░рдорд┐рдд рдХрд░ рджреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХрдИ "рдЪрд░" рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛, рдЬреЛ рдХрд┐ "рд▓реЗрдЦрди рд╕рдордп" рдкрд░ рдЖрд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИрдВ рдпрд╛ рдХреЗрд╡рд▓ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рдкрдврд╝рдХрд░ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдХрдард┐рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред #[debug_result] рдХреЛ рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рдЦрд░рд╛рдм рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдлрд╝рдВрдХреНрд╢рди рдорд╛рди рдЕрд╕рд╛рдЗрди рдХрд┐рдП рдЧрдП рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдпрджрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди #[debug_result] рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИ рдФрд░ рдПрдХ рдирд╣реАрдВ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреАред

// f3 is not annotated
fn f3() -> Result<X, Y>;

// later inside of a function:
   // z2 needs to be both marked spoiled and non-spoiled -> type error
   let z2 = if a() {
       f3()
   } else {
       f()
   };
   // althrough the following would be possible:
   let z2_ = if a() {
       f3()?
   } else {
       f()?
   };

рд╡реИрдХрд▓реНрдкрд┐рдХ: рдПрдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдПрдХ "рдХреНрд▓реАрдирд░" рд╕рдорд╛рдзрд╛рди рдПрдХ DebugResult<T, E> рдкреНрд░рдХрд╛рд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдХрд▓рди рдзреНрд╡рдЬ рд╕реЗрдЯ рд╣реЛрдиреЗ рдкрд░ рдмрд╕ рдШрдмрд░рд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреНрдпрдерд╛ Result<T, E> рдмрд░рд╛рдмрд░ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рдореМрдЬреВрджрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рднреА рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдореБрдЭреЗ рднреА рд▓рдЧрддрд╛ рд╣реИред

@zserik рдХреА рдЕрдВрддрд┐рдо рдкреЛрд╕реНрдЯ рдХрд╛ рдЙрддреНрддрд░ рджреЗрдВ: рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдореИрдХреНрд░реЛ рд╡реНрдпрд░реНрде рд╣реИ - рдмрд┐рд▓реНрдб рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд░рд┐рдЯрд░реНрди рдкреНрд░рдХрд╛рд░ рдЪрд╛рд░реНрдЬ рдХрд░рдирд╛ рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рдгрд╛рдо рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдореИрдЪ рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╣рд░ рд╕рдВрднрд╡ рдмрд┐рд▓реНрдб рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рддреЛрдбрд╝ рджреЗрдЧрд╛, рдЪрд╛рд╣реЗ рд╡рд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛред

@ tema3210 рдореБрдЭреЗ рдкрддрд╛ рд╣реИред рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ @Lokathor рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдЖрдо рддреМрд░ рдкрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ рдЬреЛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреА рд╣реИ рд╡рд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдХрдИ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде, рдЬреЛ рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИ:

// the result of the fn *must* have Try<Ok=()>
// btw. the macro could be already implemented with a proc_macro today.
#[debug_result]
fn x() -> Result<(), XError> {
  /* ..{xbody}.. */
}

// e.g. evaluates roughly to:
//..begin eval
fn x_inner() -> Result<(), XError> {
  /* ..{xbody}.. */
}

#[cfg(panic_on_err)]
fn x() {
  let _: () = x_inner().unwrap();
}
#[cfg(not(panic_on_err))]
fn x() -> Result<(), XError> {
  x_innner()
}

//..end eval

fn y() -> Result<(), YError> {
  /* ... */
  // #[debug_result] results can't be matched on and can't be assigned to a
  // variable, they only can be used together with `?`, which would create
  // an asymetry in the type system, but could otherwise work, althrough
  // usage would be extremely restricted.
  x()?;
  // e.g. the following would fail to compile because capturing the result
  // is not allowed
  if let Err(z) = x() {
    // ...
  }
}

@zserik рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХрд╛ рд░реВрдк рд▓реЗрддрд╛ рд╣реИ?

#[cfg(panic_on_err)]
fn x() -> Result<(), !> {
  let _: () = x_inner().unwrap();
}

#[cfg(not(panic_on_err))]
fn x() -> Result<(), XError> {
  x_innner()
}

рдмрдврд╝рд┐рдпрд╛! рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред

рдореБрдЭреЗ рд╕рдЪ рдореЗрдВ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╕реНрдерд┐рд░реАрдХрд░рдг рд╕реЗ рдкрд╣рд▓реЗ рд╣рд┐рд╕рд╛рдм рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рддреНрд░реБрдЯрд┐ рд╡рд╛рдкрд╕реА рдХреЗ рдирд┐рд╢рд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╛ рдХрдо рд╕реЗ рдХрдо рдЗрд╕рдХреЗ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдкрд░рд┐рд╡рд░реНрддрди рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Result рд▓рд┐рдПред рдЖрдЦрд┐рд░рдХрд╛рд░ рдореИрдВ рдЗрд╕реЗ рдЖрд░рдПрдлрд╕реА рдореЗрдВ рдмрджрд▓рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреЛрд╢рд┐рд╢ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕реНрдерд┐рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдмрд╛рдж рдореЗрдВ рдЗрд╕реЗ рдЬреЛрдбрд╝рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрд░рдПрдлрд╕реА рдиреЗ рдХрд╣рд╛ рдХрд┐ рдореБрдЭреЗ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдореВрд▓ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИред

рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рдЯреНрд░реИрдХрд┐рдВрдЧ рдЬрд╛рдирдХрд╛рд░реА рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреАрдЫреЗ рдХреА рд╕рдВрдЧрддрддрд╛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЯреА рдХреЗ рд▓рд┐рдП рдПрдХ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЗрдореНрдкреНрд▓рд╛рдВрдЯ рд╣реЛрддрд╛ рд╣реИ

pub trait Track {
    fn track(&mut self, location: &'static Location<'static>);
}

default impl<T> Track for T {
    fn track(&mut self, _: &'static Location<'static>) {}
}

рдФрд░ рдлрд┐рд░ рдЖрдк Try рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ Result рдХреЗ рд▓рд┐рдП track_caller рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ,

    #[track_caller]
    fn from_error(mut v: Self::Error) -> Self {
        v.track(Location::caller());
        Self::Err(v)
    }

рдФрд░ рдлрд┐рд░ рдЙрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдЕрдкрдиреЗ рд▓рд┐рдП рдЯреНрд░реИрдХ . рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрдХрдЯреНрд░реЗрд╕ рдПрдХрддреНрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ

#[derive(Debug, Default)]
pub struct ReturnTrace {
    frames: Vec<&'static Location<'static>>,
}

impl Track for ReturnTrace {
    fn track(&mut self, location: &'static Location<'static>) {
        self.frames.push(location);
    }
}

рдЙрдкрдпреЛрдЧ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ

#![feature(try_blocks)]
use error_return_trace::{MyResult, ReturnTrace};

fn main() {
    let trace = match one() {
        MyResult::Ok(()) => unreachable!(),
        MyResult::Err(trace) => trace,
    };

    println!("{:?}", trace);
}

fn one() -> MyResult<(), ReturnTrace> {
    try { two()? }
}

fn two() -> MyResult<(), ReturnTrace> {
    MyResult::Err(ReturnTrace::default())?
}

рдФрд░ рдмреИрдХрдЯреНрд░реЗрд╕ рдХреЗ рдПрдХ рдмрд╣реБрдд рд╣реА рдЪрдордХрджрд╛рд░ рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ

ReturnTrace { frames: [Location { file: "examples/usage.rs", line: 18, col: 42 }, Location { file: "examples/usage.rs", line: 14, col: 16 }] }

рдФрд░ рдпрд╣рд╛рдБ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдЗрд╕рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдкреНрд░рдорд╛рдг рд╣реИ https://github.com/yaahc/error-return-traces

рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдХреЗрд╡рд▓ рдПрдХ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдЬрд┐рд╕реЗ рд╣рдо рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХрд░реНрддрд╛ рдХрд╛

trait Try{
     type Error;
     type Ok;
     fn into_result(self)->Result<Self::Ok,Self::Error>;
     fn from_ok(val: Self::Ok)->Self;
     fn from_error<T>(val: T)->Self;
}

рдзреНрдпрд╛рди рджреЗрдВ, рд╡рд╣рд╛рдВ рдХрдВрдкрд╛рдЗрд▓рд░ from_error рдХреЛ рдореЛрдиреЛрдореЛрд░реНрдлрд╛рдЗрдЬ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, From::from рдХреЙрд▓ рд╕реЗ рдмрдЪ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдХреЛрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╡рд┐рдзрд┐ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк ? рдСрдкрд░реЗрдЯрд░ рдХреА рдХреНрд╖рдорддрд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ "рдЕрдирд░реИрдк" рдХрд░ рд╕рдХрддреА рд╣реИред рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ред

 fn from_error<T>(val: T)->Self;

рдЬреИрд╕рд╛ рдХрд┐ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХрд░реНрддрд╛ рдХреЛ _any_ рдЖрдХрд╛рд░ T рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЕрдкреНрд░рддрд┐рдмрдВрдзрд┐рддред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдХрд╕реНрдЯрдо рд╡рд┐рд╡рд╢ рд╣реЛрдиреЗ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕реЗ Try<T> ред рдпрд╣ TryBlock / Bubble<Other> рд╕рдВрдпреЛрдЬрди рдХреЗ рд╕рдорд╛рди рд╣реИ рдЬреЛ @scottmcm рдореЗрдВ https://github.com/rust-lang/rust/issues/42327#issuecomment-457353299 рдореЗрдВ рдерд╛ред

рдЬреИрд╕рд╛ рд▓рд┐рдЦрд╛ рд╣реИ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХрд░реНрддрд╛ рдХреЛ _any_ рдЖрдХрд╛рд░ T рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЕрдкреНрд░рддрд┐рдмрдВрдзрд┐рддред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдХрд╕реНрдЯрдо рд╡рд┐рд╡рд╢ рд╣реЛрдиреЗ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреИрд╕реЗ Try<T> ред рдпрд╣ TryBlock / Bubble<Other> рд╕рдВрдпреЛрдЬрди рдХреЗ рд╕рдорд╛рди рд╣реИ рдЬреЛ @scottmcm рдореЗрдВ #42327 (рдЯрд┐рдкреНрдкрдгреА) рдореЗрдВ рдерд╛ ред

рдореЗрд░рд╛ рдорддрд▓рдм рдерд╛ рдХрд┐ рдЙрдкрдпреЛрдЧ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:

trait Try{
     //same from above
}
struct Dummy {
    a: u8,
}
struct Err1();
struct Err2();
impl Try for Dummy {
    type Ok=();
    type Error=();

    fn into_result(self)->Result<Self::Ok,Self::Error>{
        std::result::Result::Ok(())
    }
    fn from_ok(val: Self::Ok)->Self{
        Self{a: 0u8}
    }
    fn from_error<T>(val: Err1)->Self where T == Err1{
        Self{a: 1u8}
    }
    fn from_error<T>(val: Err2)->Self where T == Err2{
        Self{a: 2u8}
    }
}

рдЖрдкрдХреЛ рдХреЛрд╢рд┐рд╢ рдФрд░ TryFromError рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдореБрдЭреЗ рдпрд╣ рдореВрд▓ рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдкрд╕рдВрдж рд╣реИ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдПрдХ рдирдП рдЖрд░рдПрдлрд╕реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

(рдФрд░ рдореБрдЭреЗ рдЕрднреА рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ "рдХреЛрд╢рд┐рд╢" рдХреЗ рдмрдЬрд╛рдп "рдкреНрд░рдЪрд╛рд░" рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдкрдЪрд╛рддрд╛ рд╣реВрдВ)

@ tema3210 рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдЖрдкрдХрд╛ рдЗрд░рд╛рджрд╛ рд╕рдордЭрддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдорд╛рдиреНрдп рдЬрдВрдЧ рдирд╣реАрдВ рд╣реИред

@ SonyEx2

рдЖрдкрдХреЛ рдХреЛрд╢рд┐рд╢ рдФрд░ TryFromError рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред

рдареАрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ TryBlock / Bubble<Other> рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИред рд╣рдо рдЙрд╕ рдирд╛рдордХрд░рдг рд╡рд┐рдХрд▓реНрдк рдкрд░ рдмрд╣рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд┐рдЪрд╛рд░ рдпрд╣ рдерд╛ рдХрд┐ рдЬрд▓реНрджреА рд╡рд╛рдкрд╕реА рд╣рдореЗрд╢рд╛ _errors_ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрд╣реБрдд рд╕реА рдЖрдВрддрд░рд┐рдХ Iterator рд╡рд┐рдзрд┐рдпрд╛рдВ рдХрд╕реНрдЯрдо LoopState рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реА рд╣реИрдВред find рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП, рдЖрдк рдЬреЛ рдЦреЛрдЬ рд░рд╣реЗ рд╣реИрдВ рдЙрд╕реЗ рдвреВрдВрдврдиреЗ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рд╡рд╣рд╛рдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЛ рд░реЛрдХрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

https://github.com/rust-lang/rust/blob/3360cc3a0ea33c84d0b0b1163107b1c1acbf2a69/src/libcore/iter/mod.rs#L375 -L378

рд╣рдо рдЙрд╕ рдирд╛рдордХрд░рдг рд╡рд┐рдХрд▓реНрдк рдкрд░ рдмрд╣рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд┐рдЪрд╛рд░ рдпрд╣ рдерд╛ рдХрд┐ рдЬрд▓реНрджреА рд╡рд╛рдкрд╕реА рд╣рдореЗрд╢рд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред

рдареАрдХ рд╣реИ рдХрд┐ рдореБрдЭреЗ "рдХреЛрд╢рд┐рд╢" рдирд╛рдо рдХреНрдпреЛрдВ рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ рдФрд░ "рдкреНрд░рдЪрд╛рд░" рдирд╛рдо рдкрд╕рдВрдж рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ "рдкреНрд░рд╛рд░рдВрднрд┐рдХ" рд╡рд╛рдкрд╕реА рдХрд╛ "рдкреНрд░рдЪрд╛рд░" рдХрд░рддрд╛ рд╣реИ: рдкреА

(рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ? рдкрд┐рдЫрд▓реА рдмрд╛рд░ рдЬрдм рдореИрдВрдиреЗ рдЗрд╕реЗ "рдкреНрд░рдЪрд╛рд░" рдХрд┐рдпрд╛ рдерд╛, рддреЛ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдореБрдЭреЗ рдХреЗрд╡рд▓ рд╕рдордЭ рдореЗрдВ рдЖрдпрд╛ рдФрд░ рдореИрдВ рдЗрд╕реЗ рджреВрд╕рд░реЛрдВ рдХреЛ рд╕рдордЭрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рдерд╛ред)

рдбреАрдмрдЧ рдЬрд╛рдирдХрд╛рд░реА (рдЬреИрд╕реЗ рдлрд╝рд╛рдЗрд▓/рд▓рд╛рдЗрди рдирдВрдмрд░) рд▓реЙрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЙрдЧ рд╣реБрдХ рдлрд╝реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ ? рд╡реНрдпрд╡рд╣рд╛рд░ fe рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд┐рд╕реА рднреА рдорджрдж рдХреА рд╣реЛрдЧреА?

рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдпрд╣ stdlib рдореИрдХреНрд░реЛрдЬрд╝ рдХреЛ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ ? рдСрдкрд░реЗрдЯрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ try! рдореИрдХреНрд░реЛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдмрджрдХрд┐рд╕реНрдорддреА рд╕реЗред

@stevenroose рдХреЗрд╡рд▓ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрд╕ рд╕реНрдерд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рд╕реНрдерд╛рди рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рдВрд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬрд╣рд╛рдВ ? "рд╣реЛ рдЧрдпрд╛" .

@stevenroose рдХреЗрд╡рд▓ Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрд╕ рд╕реНрдерд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рд╕реНрдерд╛рди рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Try рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рдВрд╢реЛрдзрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬрд╣рд╛рдВ ? "рд╣реЛ рдЧрдпрд╛" .

рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИ, #[track_caller] рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓рдХреНрд╖рдгреЛрдВ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ рдПрдиреЛрдЯреЗрд╢рди рд╢рд╛рдорд┐рд▓ рди рд╣реЛ

@stevenroose рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рд╛рдБ, рд╣рд╛рд▓рд╛рдБрдХрд┐ рдпрджрд┐ рдЖрдк рд╕рднреА ? рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рддреНрд░реБрдЯрд┐ рдХрд╛ рдкреНрд░рдЪрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдКрдкрд░ рд╕реЗ рддреНрд░реБрдЯрд┐ рд╡рд╛рдкрд╕реА рдЯреНрд░реЗрд╕ рдЯрд┐рдкреНрдкрдгреА рдХреА рдЬрд╛рдБрдЪ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП

https://github.com/rust-lang/rust/issues/42327#issuecomment -619218371

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХрд┐рд╕реА рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рд╣рдо impl Try for bool , рд╢рд╛рдпрдж Try<Ok=(), Error=FalseError> ?
рддрд╛рдХрд┐ рд╣рдо рдРрд╕рд╛ рдХреБрдЫ рдХрд░ рд╕рдХреЗрдВ

fn check_key(v: Vec<A>, key: usize) -> bool {
  let x = v.get_mut(key)?; // Option
  x.is_valid()?; // bool
  x.transform()?; // Result
  true
}

рдЕрдм рдореБрдЭреЗ рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд░рд┐рдЯрд░реНрди рдЯрд╛рдЗрдк Option<()> рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд╣рд╛рдВ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ ? рдХреЛрдб рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдХрд┐рд╕реА рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдХреНрдпрд╛ рд╣рдо impl Try for bool , рд╢рд╛рдпрдж Try<Ok=(), Error=FalseError> ?

рдпрд╣ Try рдХреЛ bool s рдкрд░ && рдСрдкрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдЧрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдЕрдиреНрдп рдиреЗ рдКрдкрд░ рдмрддрд╛рдпрд╛ рд╣реИ, рд╕рдлрд▓рддрд╛ рдкрд░ рд╢реЙрд░реНрдЯ-рд╕рд░реНрдХрд┐рдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рднреА рд╣реИрдВ, рдРрд╕реЗ рдореЗрдВ Try рдХреЛ || рд░реВрдк рдореЗрдВ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪреВрдВрдХрд┐ && рдФрд░ || рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рд▓рд╛рдн рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИред

@calebsander рдХреГрдкрдпрд╛ рдЙрддреНрддрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рдпрд╣ рдХреБрдЫ рд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдЪ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЕрдХреНрд╕рд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрднреА рднреА рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдЬреИрд╕реЗ let x = v.get_mut(key)? рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рдЕрдЧрд░ && рдФрд░ || рд╣рдореЗрд╢рд╛ рдЪрд╛рд▓ рдЪрд▓реЗрдВрдЧреЗ, рддреЛ рд╣рдо .unwrap_or_else() , .and_then() рдХреЗ рд╕рд╛рде Option рдФрд░ Error рдорд╛рдорд▓реЗред
рдХреНрдпрд╛ рдЖрдк рдкреНрд░рд╡рд╛рд╣рд┐рдд рдХреЛрдб рдХреЛ && рдФрд░ || рдореЗрдВ рд╡реНрдпрдХреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

fn check_key(v: Vec<A>, key: usize) -> bool {
  let x = v.get_mut(key)?; // Option
  x.not_valid().not()?; // bool
  for i in x.iter() {
    if i == 1 { return true }
    if i == 2 { return false }
    debug!("get {}" i);
  }
  let y = x.transform()?; // Result
  y == 1
}

рдХреБрдЫ рд╢рд░реНрддреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐ true рдЕрд░реНрде рд╡рд┐рдлрд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдЬрдмрдХрд┐ false рдЕрд░реНрде рд╕рдлрд▓рддрд╛ рд╣реИ, !expr? рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЪрд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП expr.not()? рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдиреЛрдЯ: рдХреЗ рд▓рд┐рдП ops::Try , рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ false рд▓рд┐рдП Error )

рдпрд╣ рдХреБрдЫ рд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдЪ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЕрдХреНрд╕рд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрднреА рднреА рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдЬреИрд╕реЗ let x = v.get_mut(key)? рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдареАрдХ рд╣реИ, рдЬрдм рддрдХ рдореИрдВ рдЖрдкрдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЛ рдЧрд▓рдд рдирд╣реАрдВ рд╕рдордЭрддрд╛, рдХреЗрд╡рд▓ Try<Ok = (), Error = FalseError> рд▓рд┐рдП bool рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реЛрдЧреАред рдЖрдкрдХреЛ impl From<NoneError> for FalseError рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рддрд╛рдХрд┐ ? рдСрдкрд░реЗрдЯрд░ None рдХреЛ false рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░ рд╕рдХреЗред (рдФрд░ рдЗрд╕реА рддрд░рд╣, рдЖрдк рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИ, рддреЛ ? рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ Result<T, E> рдХреЗ рдЕрдВрджрд░ рдПрдХ рд╕рдорд╛рд░реЛрд╣ рд╣реИ рдХрд┐ рд░рд┐рдЯрд░реНрди bool , рдЖрдк рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА impl From<E> for FalseError ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдХрдВрдмрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реЛрдЧрд╛ред) рдЖрдк рдХреЗрд╡рд▓ some_option().ok_or(false)? рдФрд░ some_result().map_err(|_| false)? рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рдЖрдк рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп Result<bool, bool> рд╕рд╛рде рдареАрдХ рд╣реИрдВ (рдЬрд┐рд╕реЗ рдЖрдк .unwrap_or_else(|err| err) рд╕рд╛рде рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдЕрдиреНрдп Try рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ bool рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рдореБрджреНрджреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░, Try рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛ рдЖрдк bool рд▓рд┐рдП рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рдХреЗрд╡рд▓ && рдСрдкрд░реЗрдЯрд░ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпреЗ рд╕рдордХрдХреНрд╖ рд╣реИрдВ

fn using_try() -> bool {
    some_bool()?;
    some_bool()?;
    some_bool()
}

рддрдерд╛

fn using_and() -> bool {
    some_bool() &&
    some_bool() &&
    some_bool()
}

(рдЬрд╛рд╣рд┐рд░ рд╣реИ, if рдФрд░ loop рдЬреИрд╕реЗ рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рд╡рд╛рд╣ рдЬреЛ рдЧреИрд░- () рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдо рд╕рд░рд▓ рд╣реИрдВред)

рдХреБрдЫ рд╢рд░реНрддреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐ true рдЕрд░реНрде рд╡рд┐рдлрд▓ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдЬрдмрдХрд┐ false рдЕрд░реНрде рд╕рдлрд▓рддрд╛ рд╣реИ, !expr? рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЪрд╛рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП expr.not()? рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдиреЛрдЯ: рдХреЗ рд▓рд┐рдП ops::Try , рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ false рд▓рд┐рдП Error )

рдореБрдЭреЗ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ false рдХреЛ Error рдорд╛рдорд▓реЗ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Iterator.all() рдЪрд╛рд╣реЗрдЧрд╛ false рд╢реЙрд░реНрдЯ рд╕рд░реНрдХрд┐рдЯ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди Iterator::any() рдЪрд╛рд╣реЗрдЧрд╛ true рдмрдЬрд╛рдпред) рдЖрдкрдХреЗ рдХрд╣реЗ, рддреЛ рдЖрдк рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдорд╛рди рдХреЛ ? (рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░рд┐рдЯрд░реНрди рдорд╛рди рдХреЛ рднреА рдЙрд▓рдЯ рдХрд░) рд╡рд┐рдкрд░реАрдд рд╢реЙрд░реНрдЯ-рд╕рд░реНрдХрд┐рдЯрд┐рдВрдЧ рд╡реНрдпрд╡рд╣рд╛рд░ред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рдкрдардиреАрдп рдХреЛрдб рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡реНрдпрд╡рд╣рд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ struct s And(bool) рдФрд░ Or(bool) рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХрд╛ рдЕрдзрд┐рдХ рдЕрд░реНрде рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдФрд░ рдЗрд╕реА рддрд░рд╣, рдпрджрд┐ рдЖрдк рдЖрд╡реЗрджрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдПрдХ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдПрдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ рдЬреЛ рдмреВрд▓ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЖрдкрдХреЛ From . рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАрдЭреВрдареА рддреНрд░реБрдЯрд┐ рдХреЗ рд▓рд┐рдПред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдХрдВрдмрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд╣реЛрдЧрд╛ред

рдирд╣реАрдВ, рдореИрдВ impl From<T> for FalseError рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛, рд╢рд╛рдпрдж рд╣рдо result.ok()? рдХрд░ рд╕рдХреЗрдВ

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрд╕рддреНрдп рдХреЛ рддреНрд░реБрдЯрд┐ рдорд╛рдорд▓реЗ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд╣реИ рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ bool::then рдЬреЛ true рд╕реЗ Some рдирдХреНрд╢рд╛ рд╣реИред

рдЕрдЧрд░ рдореИрдВ рдЪреВрдХ рдЧрдпрд╛ рддреЛ рдореБрдЭреЗ рдХреНрд╖рдорд╛ рдХрд░реЗрдВ - NoneError рдЕрд░реНрде std::error::Error рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реИ? рдпрд╣ Box<dyn Error> рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреЗрдХрд╛рд░ рдмрдирд╛рддрд╛ рд╣реИред

рдЕрдЧрд░ рдореИрдВ рдЪреВрдХ рдЧрдпрд╛ рддреЛ рдореБрдЭреЗ рдХреНрд╖рдорд╛ рдХрд░реЗрдВ - NoneError рдЕрд░реНрде std::error::Error рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реИ? рдпрд╣ Box<dyn Error> рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмреЗрдХрд╛рд░ рдмрдирд╛рддрд╛ рд╣реИред

рдпрд╣рд╛рдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ "рдХреБрдЫ None рдФрд░ рдЖрдкрдиреЗ рдЗрд╕реЗ Some рд╣реЛрдиреЗ рдХреА рдЙрдореНрдореАрдж рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧреА рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдорд╕реНрдпрд╛рдПрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ" (рдЬреЛ рдореВрд▓ рд░реВрдк рд╕реЗ рдЖрдк рдХреНрдпрд╛ рд╣реИрдВ рдпрд╣рд╛рдБ рд▓рд╛рдн рд╣реЛрдЧрд╛ - рдХреБрдЫ рдиреИрджрд╛рдирд┐рдХ тАЛтАЛрд╕рдВрджреЗрд╢)ред рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдореЗрдВ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХрд┐рд╕реА рдЕрдиреНрдп рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Option::ok_or_else рд╕рдВрдпреЛрдЬрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреЙрд▓рд┐рдВрдЧ рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рдореЗрд░реЗ рдкрд╛рд╕ рд╡реИрд╕реЗ рднреА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдорддреМрд░ рдкрд░ рдмреЗрд╣рддрд░ рд╕рдВрджрд░реНрдн рд╣реЛрддрд╛ рд╣реИред

рдореИрдВ @ErichDonGubler рд╕реЗ рд╕рд╣рдордд рд╣реВрдВред ? рд╕рд╛рде Option рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рд╣реЛрдирд╛ рдмрд╣реБрдд рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдПрдХ рдЕрдЪреНрдЫреЗ рдХрд╛рд░рдг рдХреЗ рд▓рд┐рдП рд╣реИ, рдФрд░, рдПрдХ рднрд╛рд╖рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдареАрдХ рд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛ рд╣рд░ рдХрд┐рд╕реА рдХреЗ рд╣рд┐рдд рдореЗрдВ рд╣реИред рдХреЗрд╡рд▓ ? None рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рддреНрд░реБрдЯрд┐ рд╕рдВрджрд░реНрдн рдХреЛ

рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рдЬрдм рдореИрдВ None рдХреЛ рддреНрд░реБрдЯрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреВрдВрдЧрд╛, рд╡рд╣ рдмрд╣реБрдд рд╣реА рдореЛрдЯреЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдкрд░ рд╣реИред рдореИрдВрдиреЗ рд╕реЛрдЪрд╛, рдЕрдЧрд░ рд╣рдо Option::todo_err() рдХреЙрд▓ рдХреА рддрд░рд╣ рдХреБрдЫ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЖрдВрддрд░рд┐рдХ рдореВрд▓реНрдп рдХреЗ Ok рд▓реМрдЯрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди None ред рдЬрдм рддрдХ рдЖрдк рдХреЛрдб рд╕рдВрд▓реЗрдЦрди рдХреЗ "рд░рдл рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдкрд┐рдВрдЧ" рдореЛрдб рдХреА рдЬрд░реВрд░рддреЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддрдм рддрдХ рдпрд╣ рдмрд╣реБрдд рдкреНрд░рддрд┐-рд╕рд╣рдЬ рд╣реИред рдпрд╣ рдмрд╣реБрдд рд╣рдж рддрдХ Ok(my_option.unwrap()) , рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП Ok(...) рд░реИрдкрд┐рдВрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ "рдЯреВрдбреВ" рдкреНрд░рдХреГрддрд┐ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЗрд╕ рдХреЛрдб рдХреЛ рдЙрддреНрдкрд╛рджрди рддрд░реНрдХ рд╕реЗ рд╣рдЯрд╛рдиреЗ рдХреЗ рдЗрд░рд╛рджреЗ рд╕реЗ рд╕рдВрдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдЙрдЪрд┐рдд рддреНрд░реБрдЯрд┐ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХреЗ рд╕рд╛рде рдмрджрд▓ рджреЗрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдШрдмрд░рд╛рдПрдЧрд╛ рдХреЛрдИ рдирд╣реАрдВ

рджреГрдврд╝рддрд╛ рд╕реЗ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ рдХрд┐ рд╣рдореЗрдВ рдЗрд╕реЗ рдХреЗрд╡рд▓ unwrap рдЫреЛрдбрд╝ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╣рдордиреЗ рдПрдХ todo_err рдЬреЛрдбрд╝рд╛ рд╣реИ рддреЛ рдЙрд╕реЗ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдпрд╣ рдкреНрд░рд╢реНрди рдкреВрдЫрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рддреНрд░реБрдЯрд┐ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реИред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ fn todo_err(self) -> Result<Self, !> ! рдХреЛ рд╕реНрдерд┐рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП

рдореЗрд░рд╛ рдЙрдкрдпреЛрдЧрдХреЗрд╕ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдореЛрдЯрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╣реИ рдЬрд╣рд╛рдВ рдореБрдЭреЗ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдмрд╣реБрдд рдЕрдзрд┐рдХ рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рд╣реИред рдХреНрдпрд╛ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рд╕реВрдЪреАрдмрджреНрдз рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рд╕рдВрдкреВрд░реНрдг NoneError рдкреАрдбрд╝рд┐рдд рдирд╣реАрдВ рд╣реИ? рдЕрдЧрд░ рдпрд╣ рддрдп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрд╕реНрддрд┐рддреНрд╡ рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИ, рдХрдо рд╕реЗ рдХрдо рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП), рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдЗрд╕реЗ Error рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рдПрдХ рдирд╛рдо рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдХрдореА рдХреЗ рдХрд╛рд░рдг рдореИрдВрдиреЗ рдЙрд╕ рдкрд░ рдХреЗрд╡рд▓ .ok_or("error msg") рдердкреНрдкрдбрд╝ рдорд╛рд░рдиреЗ рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓рд┐рдпрд╛, рдЬреЛ рдХрд╛рдо рднреА рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдХрдо рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

nikomatsakis picture nikomatsakis  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

lambda-fairy picture lambda-fairy  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Robbepop picture Robbepop  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dwrensha picture dwrensha  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

tikue picture tikue  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ