如何自动实现FromIterator?

时间:2016-11-19 01:15:28

标签: iterator rust

我写了一个特征,指出了一些类似于Vec的方法:

pub trait Buffer {
    type Item;
    fn with_capacity(c: usize) -> Self;
    fn push(&mut self, item: Self::Item);
}

我想为实施Buffer的所有类型实施FromIterator,如下所示:

impl<T> iter::FromIterator<T::Item> for T
    where T: Buffer
{
    fn from_iter<I>(iter: I) -> Self
        where I: IntoIterator<Item = T>
    {
        let mut iter = iter.into_iter();
        let (lower, _) = iter.size_hint();
        let ans = Self::with_capacity(lower);
        while let Some(x) = iter.next() {
            ans.push(x);
        }
        ans
    }
}

编译器不允许我:

error[E0210]: type parameter `T` must be used as the type parameter
for some local type (e.g. `MyStruct<T>`); only traits defined in the
current crate can be implemented for a type parameter

我想我理解错误信息;它阻止我编写与标准库未来可能更改不兼容的代码。

解决此错误的唯一方法似乎是为我实施FromIterator的每种类型单独实施Buffer。这将涉及多次复制完全相同的代码。有没有办法在所有Buffer类型之间共享相同的实现?

1 个答案:

答案 0 :(得分:0)

您无法从另一个箱子中为任意类型实施特征,仅适用于您的箱子中的类型。但是,您可以将实现移动到函数并减少重复代码的数量:

fn buffer_from_iter<I, B>(iter: I) -> B
    where I: IntoIterator<Item = B::Item>, 
          B: Buffer
{
    let mut iter = iter.into_iter();
    let (lower, _) = iter.size_hint();
    let mut ans = B::with_capacity(lower);
    while let Some(x) = iter.next() {
        ans.push(x);
    }
    ans
}

struct S1;
impl Buffer for S1 {
    type Item = i32;
    fn with_capacity(c: usize) -> Self { unimplemented!() }
    fn push(&mut self, item: Self::Item) { unimplemented!() }
}

impl std::iter::FromIterator<<S1 as Buffer>::Item> for S1 {
    fn from_iter<I>(iter: I) -> Self
        where I: IntoIterator<Item = <S1 as Buffer>::Item>
    {
        buffer_from_iter(iter)
    }
}

FromIterator的此实现可以包装到宏中,以进一步减少代码重复。