0

元のエラーが転送される別のoverを生成するために、 がジェネリックであるIterator<Item = Result<Type, E>>すべての拡張特性を実装しようとしています。EIteratorResult<OtherType, E>

問題は、変換Type -> OtherTypeが失敗する可能性があることです (関数はf(t: Type) -> Result<OtherType, ConcreteError>.

したがって、反復Eは基礎となるイテレーターまたは具体的なエラー型から (ジェネリック) を返す可能性がありますが、これはもちろん不可能です。

これを実装する方法は?

最小限の例:

pub struct A;
pub struct B;
pub struct CongreteError;

fn transform(a: A) -> Result<B, CongreteError> {
    Ok(B {})
}

pub struct ExtensionIter<E>(Box<Iterator<Item = Result<A, E>>>);

impl<E> Iterator for ExtensionIter<E> {
    type Item = Result<B, E>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.0.next() {
            Some(Ok(a)) => Some(transform(a)),
            Some(Err(e)) => Some(Err(e)),
            None => None,
        }
    }
}

pub trait Extension<E> {
    fn extend(self) -> ExtensionIter<E>;
}

impl<E, I> Extension<E> for I
where
    I: Iterator<Item = Result<A, E>>,
{
    fn extend(self) -> ExtensionIter<E> {
        ExtensionIter(Box::new(self))
    }
}

fn main() {
    let v: Vec<A> = vec![];
    for element in v.iter().extend() {
        match element {
            Ok(b) => {}
            Err(e) => {}
        }
    }
}

遊び場

エラー:

error[E0308]: mismatched types
  --> src/main.rs:16:33
   |
16 |             Some(Ok(a)) => Some(transform(a)),
   |                                 ^^^^^^^^^^^^ expected type parameter, found struct `CongreteError`
   |
   = note: expected type `std::result::Result<_, E>`
              found type `std::result::Result<_, CongreteError>`
   = help: here are some functions which might fulfill your needs:
           - .map_err(...)
           - .or(...)
           - .or_else(...)

error[E0310]: the parameter type `I` may not live long enough
  --> src/main.rs:32:23
   |
27 | impl<E, I> Extension<E> for I
   |         - help: consider adding an explicit lifetime bound `I: 'static`...
...
32 |         ExtensionIter(Box::new(self))
   |                       ^^^^^^^^^^^^^^
   |
note: ...so that the type `I` will meet its required lifetime bounds
  --> src/main.rs:32:23
   |
32 |         ExtensionIter(Box::new(self))
   |                       ^^^^^^^^^^^^^^

error[E0599]: no method named `extend` found for type `std::slice::Iter<'_, A>` in the current scope
  --> src/main.rs:38:29
   |
38 |     for element in v.iter().extend() {
   |                             ^^^^^^
   |
   = note: the method `extend` exists but the following trait bounds were not satisfied:
           `std::slice::Iter<'_, A> : Extension<_>`
           `&std::slice::Iter<'_, A> : Extension<_>`
           `&mut std::slice::Iter<'_, A> : Extension<_>`
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `extend`, perhaps you need to implement it:
           candidate #1: `Extension`
4

1 に答える 1