使用“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
存在):
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),
})
}
}
我似乎遇到了 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 pointerfn(&str) -> std::result::Result<IteratorHolder<I, T>, _>
found fn pointerfn(&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 structCustomIterator
[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
存在):
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),
})
}
}