pub trait Try: FromResidual {
type Output;
type Residual;
// Required methods
fn from_output(output: Self::Output) -> Self;
fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
}
try_trait_v2
)Expand description
The ?
operator and try {}
blocks.
try_*
methods typically involve a type implementing this trait. For
example, the closures passed to Iterator::try_fold
and
Iterator::try_for_each
must return such a type.
Try
types are typically those containing two or more categories of values,
some subset of which are so commonly handled via early returns that it’s
worth providing a terse (but still visible) syntax to make that easy.
This is most often seen for error handling with Result
and Option
.
The quintessential implementation of this trait is on ControlFlow
.
§Using Try
in Generic Code
Iterator::try_fold
was stabilized to call back in Rust 1.27, but
this trait is much newer. To illustrate the various associated types and
methods, let’s implement our own version.
As a reminder, an infallible version of a fold looks something like this:
fn simple_fold<A, T>(
iter: impl Iterator<Item = T>,
mut accum: A,
mut f: impl FnMut(A, T) -> A,
) -> A {
for x in iter {
accum = f(accum, x);
}
accum
}
So instead of f
returning just an A
, we’ll need it to return some other
type that produces an A
in the “don’t short circuit” path. Conveniently,
that’s also the type we need to return from the function.
Let’s add a new generic parameter R
for that type, and bound it to the
output type that we want:
fn simple_try_fold_1<A, T, R: Try<Output = A>>(
iter: impl Ite