将范围作为结构字段

Taking a range as a struct field

有多种Range类型。一些 Range 类型实现了 Iterator。我想将实现 Iterator 的所有 Range 类型作为结构字段。

这是我的方法:

pub trait RangeBoundsExt<T: PartialOrd<T>>: Iterator<Item = T> {
    // some methods
}

impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::Range<T> {}

impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeFrom<T> {}

impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeInclusive<T> {}

pub struct Foo<T> {
    range: Box<dyn RangeBoundsExt<T>>
}

Playground

但是我收到这个错误:

  Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `T: std::iter::Step` is not satisfied
 --> src/lib.rs:7:24
  |
7 | impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::Range<T> {}
  |                        ^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `T`
  |
  = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<T>`
help: consider further restricting this bound
  |
7 | impl<T: PartialOrd<T> + std::iter::Step> RangeBoundsExt<T> for std::ops::Range<T> {}
  |                       ^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `T: std::iter::Step` is not satisfied
 --> src/lib.rs:9:24
  |
9 | impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeFrom<T> {}
  |                        ^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `T`
  |
  = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::RangeFrom<T>`
help: consider further restricting this bound
  |
9 | impl<T: PartialOrd<T> + std::iter::Step> RangeBoundsExt<T> for std::ops::RangeFrom<T> {}
  |                       ^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `T: std::iter::Step` is not satisfied
  --> src/lib.rs:11:24
   |
11 | impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeInclusive<T> {}
   |                        ^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `T`
   |
   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::RangeInclusive<T>`
help: consider further restricting this bound
   |
11 | impl<T: PartialOrd<T> + std::iter::Step> RangeBoundsExt<T> for std::ops::RangeInclusive<T> {}
   |                       ^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Range 不保证 Iterator 实现。它仅在类型实现 Step 时提供一个。同样,RangeTo 不保证缺少 Iterator 实现。它只是默认不提供一个。要修复错误,您只需要求范围有一个迭代器定义:

// note the additional 'where' requirement
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::Range<T> where
    std::ops::Range<T>: Iterator<Item = T>
{
}

impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeFrom<T> where
    std::ops::RangeFrom<T>: Iterator<Item = T>
{
}

impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeInclusive<T> where
    std::ops::RangeInclusive<T>: Iterator<Item = T>
{
}