Rust 迭代器 [E0053] 和 [E0308] 使用 `From` 实现

问题描述

我似乎在使用 Rust 时遇到了问题,当然希望得到一些帮助。

我有一个实现 Iterator trait 的自定义 struct,以及一个单独的 struct(也是一个迭代器),我希望能够包装任何东西它表现为一个可迭代的。其中一些似乎可以通过泛型实现,但是,当在包装器中获得特定的 struct 时,事情似乎会走向一边。

我的主要目标是接受任何返回 Option<char> 的可迭代对象,并执行一些解析/字符集合。

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

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 实现时,会出现各种类型错误

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

方法 from_str 具有不兼容的 trait 预期 fn 指针类型 fn(&str) -> std::result::Result<IteratorHolder<I,T>,_> 找到 fn 指针 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,{
    type Err = ParseIntError;

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

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

不匹配的类型预期类型参数 I 发现结构 CustomIterator [E0308]

impl<I,{
    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 em> 实现。我的主要目标是拥有一个类似于 IteratorHolder 的解析器,它可以从迭代器中读取字符,而不管这些字符来自哪里;例如。文件、流、字符串。等

解决方法

正如@Aplet123 所提到的,您声称为包含 any 迭代器的 FromStr 实现 IteratorHolder,但是您实际上只想为 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),})
    }
}