迭代一系列泛型类型

时间:2018-01-18 12:13:55

标签: iterator rust traits

我有一个特质

trait B {
    type Index: Sized + Copy;
    fn bounds(&self) -> (Self::Index, Self::Index);
}

我想获得Index中的所有bounds es:

fn iterate<T: B>(it: &T) {
    let (low, high) = it.bounds();
    for i in low..high {}
}

这不起作用,因为没有约束类型T可以“范围”结束,编译器也说了这么多:

error[E0277]: the trait bound `<T as B>::Index: std::iter::Step` is not satisfied
 --> src/main.rs:8:5
  |
8 |     for i in low..high {}
  |     ^^^^^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `<T as B>::Index`
  |
  = help: consider adding a `where <T as B>::Index: std::iter::Step` bound
  = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<<T as B>::Index>`

我尝试将Step绑定到Index

use std::iter::Step;

trait B {
    type Index: Sized + Copy + Step;
    fn bounds(&self) -> (Self::Index, Self::Index);
}

但显然它不稳定:

error: use of unstable library feature 'step_trait': likely to be replaced by finer-grained traits (see issue #42168)
 --> src/main.rs:1:5
  |
1 | use std::iter::Step;
  |     ^^^^^^^^^^^^^^^

error: use of unstable library feature 'step_trait': likely to be replaced by finer-grained traits (see issue #42168)
 --> src/main.rs:4:32
  |
4 |     type Index: Sized + Copy + Step;
  |                                ^^^^

我错过了什么,或者现在是不是可以这么做?

2 个答案:

答案 0 :(得分:8)

如果你想要求Range<T>可以迭代,只需使用它作为你的特征界限:

trait Bounded {
    type Index: Sized + Copy;
    fn bounds(&self) -> (Self::Index, Self::Index);
}

fn iterate<T>(it: &T)
where
    T: Bounded,
    std::ops::Range<T::Index>: IntoIterator,
{
    let (low, high) = it.bounds();
    for i in low..high {}
}

fn main() {}

答案 1 :(得分:2)

要做到这种事情,num箱子一般都很有帮助。

extern crate num;

use num::{Num, One};
use std::fmt::Debug;

fn iterate<T>(low: T, high: T)
where
    T: Num + One + PartialOrd + Copy + Clone + Debug,
{
    let one = T::one();
    let mut i = low;
    loop {
        if i > high {
            break;
        }
        println!("{:?}", i);

        i = i + one;
    }
}

fn main() {
    iterate(0i32, 10i32);
    iterate(5u8, 7u8);
    iterate(0f64, 10f64);
}