扩展所有 Iterators<Item = Result<Type, E>> 以转换类型
Extending all Iterators<Item = Result<Type, E>> to transform type
我正在尝试为所有 Iterator<Item = Result<Type, E>>
实施扩展特征,其中 E
是通用的,以在 Result<OtherType, E>
上生成另一个 Iterator
,其中错误来自原件已转发。
问题是,转换 Type -> OtherType
可能会失败(函数是 f(t: Type) -> Result<OtherType, ConcreteError>
。
因此,迭代可能 return 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`
我高度推荐阅读The Rust Programming Language。它充满了新 Rust 程序员应该知道的信息。
might return E
[...] or a concrete error type
Rust 的一个令人兴奋的功能是 enums。枚举允许您创建可以是多种其他类型之一的类型。在这种情况下,我们可以将枚举定义为底层错误或我们自己的:
pub enum ExtensionError<E> {
Original(E),
Concrete(ConcreteError),
}
那么这只是从一种类型映射到另一种类型的问题:
pub struct A;
pub struct B;
pub struct ConcreteError;
fn transform(_: A) -> Result<B, ConcreteError> {
Ok(B {})
}
pub struct ExtensionIter<I>(I);
pub enum ExtensionError<E> {
Original(E),
Concrete(ConcreteError),
}
impl<I, E> Iterator for ExtensionIter<I>
where
I: Iterator<Item = Result<A, E>>,
{
type Item = Result<B, ExtensionError<E>>;
fn next(&mut self) -> Option<Self::Item> {
match self.0.next() {
Some(Ok(a)) => Some(transform(a).map_err(ExtensionError::Concrete)),
Some(Err(e)) => Some(Err(ExtensionError::Original(e))),
None => None,
}
}
}
pub trait Extension: Iterator {
fn extend(self) -> ExtensionIter<Self>
where
Self: Sized,
{
ExtensionIter(self)
}
}
impl<I: Iterator> Extension for I {}
fn main() {
let v: Vec<Result<A, ()>> = vec![];
for element in v.into_iter().extend() {
match element {
Ok(_) => {}
Err(_) => {}
}
}
}
我正在尝试为所有 Iterator<Item = Result<Type, E>>
实施扩展特征,其中 E
是通用的,以在 Result<OtherType, E>
上生成另一个 Iterator
,其中错误来自原件已转发。
问题是,转换 Type -> OtherType
可能会失败(函数是 f(t: Type) -> Result<OtherType, ConcreteError>
。
因此,迭代可能 return 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`
我高度推荐阅读The Rust Programming Language。它充满了新 Rust 程序员应该知道的信息。
might return
E
[...] or a concrete error type
Rust 的一个令人兴奋的功能是 enums。枚举允许您创建可以是多种其他类型之一的类型。在这种情况下,我们可以将枚举定义为底层错误或我们自己的:
pub enum ExtensionError<E> {
Original(E),
Concrete(ConcreteError),
}
那么这只是从一种类型映射到另一种类型的问题:
pub struct A;
pub struct B;
pub struct ConcreteError;
fn transform(_: A) -> Result<B, ConcreteError> {
Ok(B {})
}
pub struct ExtensionIter<I>(I);
pub enum ExtensionError<E> {
Original(E),
Concrete(ConcreteError),
}
impl<I, E> Iterator for ExtensionIter<I>
where
I: Iterator<Item = Result<A, E>>,
{
type Item = Result<B, ExtensionError<E>>;
fn next(&mut self) -> Option<Self::Item> {
match self.0.next() {
Some(Ok(a)) => Some(transform(a).map_err(ExtensionError::Concrete)),
Some(Err(e)) => Some(Err(ExtensionError::Original(e))),
None => None,
}
}
}
pub trait Extension: Iterator {
fn extend(self) -> ExtensionIter<Self>
where
Self: Sized,
{
ExtensionIter(self)
}
}
impl<I: Iterator> Extension for I {}
fn main() {
let v: Vec<Result<A, ()>> = vec![];
for element in v.into_iter().extend() {
match element {
Ok(_) => {}
Err(_) => {}
}
}
}