使用“From”实现的 Rust 迭代器 [E0053] 和 [E0308]

Rust Iterator [E0053] and [E0308] using `From` implementation

我似乎遇到了 Rust 方面的问题,当然希望得到一些帮助。

我有一个实现 Iterator 特性的自定义 struct,以及一个单独的 struct(也是一个 Iterator),我希望能够 wrap 任何将自身呈现为可迭代对象的东西。其中一些似乎可以通过泛型实现,但是,当在包装器中变得具体时 struct 事情似乎会发生变化。

我的主要目标是接受任何 returns Option<char> 的可迭代对象,并执行一些 parsing/collection 个字符。

这是一个玩具示例,演示了我要实现的核心功能...

src/main.rs

#!/usr/bin/env rust


struct IteratorHolder<I, T>
where
    I: Iterator<Item = T>
{
    iter: I,
}

impl<I, T> Iterator for IteratorHolder<I, T>
where
    I: Iterator<Item = T>
{
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

impl<I, T> IteratorHolder<I, T>
where
    I: Iterator<Item = T>
{
    #[allow(dead_code)]
    fn new(iter: I) -> Self {
        Self { iter }
    }
}

impl<I, T> From<I> for IteratorHolder<I, T>
where
    I: Iterator<Item = T>,
{
    fn from(iter: I) -> Self {
        Self { iter }
    }
}


// ============================================================================


struct CustomIterator {
    data: Option<(usize, String)>
}

impl CustomIterator {
    #[allow(dead_code)]
    fn new<S>(string: S) -> Self
    where
        S: Into<String>
    {
        let string: String = string.into();
        let data = Some((0, string));
        Self { data }
    }
}

impl Iterator for CustomIterator {
    type Item = char;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some((index, string)) = self.data.take() {
            let mut iter = string.get(index..).unwrap().char_indices();
            if let Some((_, c)) = iter.next() {
                self.data = iter.next().map(|(i, _)| (index + i, string));
                return Some(c);
            }
        }
        None
    }
}


// ============================================================================


#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn map() {
        let v = vec![1, 2, 3];
        let m = v.into_iter().map(|n| n * 2);
        let mut i = IteratorHolder::new(m);
        assert_eq!(i.next(), Some(2));
    }

    #[test]
    fn chars() {
        let s = String::from("abc");
        let c = s.chars();
        let mut i = IteratorHolder::new(c);
        assert_eq!(i.next(), Some('a'));
    }

    #[test]
    fn custom_iterator() {
        let c = CustomIterator::new("zxc");
        let mut i = IteratorHolder::new(c);
        assert_eq!(i.next(), Some('z'));
    }

    #[test]
    fn from_iter() {
        let c = CustomIterator::new("zxc");
        let mut i = IteratorHolder::from(c);
        assert_eq!(i.next(), Some('z'));
    }
}

以上似乎都可以正常运行


我发现奇怪的是,当具体使用 From 实现时,会出现各种类型错误。

例如,我在 IteratorHolder 上实施 FromStr 时会生成 E0053 错误...

method from_str has an incompatible type for trait expected fn pointer fn(&str) -> std::result::Result<IteratorHolder<I, T>, _> found fn pointer fn(&str) -> std::result::Result<IteratorHolder<CustomIterator, char>, _> [E0053]

src/main.rs(剪断)

use std::str::FromStr;
use std::num::ParseIntError;


impl<I, T> FromStr for IteratorHolder<I, T>
where
    I: Iterator<Item = T>,
{
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<IteratorHolder<CustomIterator, char>, Self::Err> {
        let iter = CustomIterator::new(s);
        let hold = IteratorHolder { iter };
        Ok(hold)
    }
}

...更通用会产生 E0308 个错误...

mismatched types expected type parameter I found struct CustomIterator [E0308]

impl<I, T> FromStr for IteratorHolder<I, T>
where
    I: Iterator<Item = T>,
{
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let iter = CustomIterator::new(s);
        let hold = Self { iter };
        Ok(hold)
    }
}

基本上我是打脸如何让IteratorHolder自给自足,关于From 实现。我的主要目标是拥有一个类似于 IteratorHolder 的解析器,它可以从迭代器中读取字符,而不管这些字符来自何处;例如。文件、流、字符串。等等

正如 @Aplet123 提到的,您声称要为包含 any 迭代器的 IteratorHolder 实现 FromStr,但是您实际上只想为IteratorHolder<CustomIterator>。这是一个工作版本,清理了一点并且更加惯用(特别是:我删除了 T 因为它是多余的,它已经作为 I::Item 存在):

Playground

use std::num::ParseIntError;
use std::str::FromStr;

struct IteratorHolder<I> {
    iter: I,
}

impl<I: Iterator> Iterator for IteratorHolder<I> {
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

impl<I: Iterator> IteratorHolder<I> {
    #[allow(dead_code)]
    fn new(iter: I) -> Self {
        Self { iter }
    }
}

impl<I: Iterator> From<I> for IteratorHolder<I> {
    fn from(iter: I) -> Self {
        Self::new(iter)
    }
}

// ============================================================================

struct CustomIterator {
    data: Option<(usize, String)>,
}

impl CustomIterator {
    #[allow(dead_code)]
    fn new<S: Into<String>>(string: S) -> Self {
        Self {
            data: Some((0, string.into())),
        }
    }
}

impl Iterator for CustomIterator {
    type Item = char;

    fn next(&mut self) -> Option<Self::Item> {
        if let Some((index, string)) = self.data.take() {
            let mut iter = string.get(index..).unwrap().char_indices();
            if let Some((_, c)) = iter.next() {
                self.data = iter.next().map(|(i, _)| (index + i, string));
                return Some(c);
            }
        }
        None
    }
}

impl FromStr for IteratorHolder<CustomIterator> {
    type Err = ParseIntError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(IteratorHolder {
            iter: CustomIterator::new(s),
        })
    }
}