Collections 如何使用迭代器特性构建通用API
我可能看不到树的森林,但我想知道我实际上如何设计我的方法,使其不针对硬集合类型,而是针对迭代器。考虑这个方法。Collections 如何使用迭代器特性构建通用API,collections,iterator,rust,traits,Collections,Iterator,Rust,Traits,我可能看不到树的森林,但我想知道我实际上如何设计我的方法,使其不针对硬集合类型,而是针对迭代器。考虑这个方法。 pub fn print_strings(strings: Vec<String>) { for val in strings.iter() { println!("{}", val); } } Playpen(也可查看冗长的编译器错误) 不幸的是,这似乎也不起作用。我缺少什么?当你在Vec上调用.iter()时,你会得到一个迭代器。因此
pub fn print_strings(strings: Vec<String>) {
for val in strings.iter() {
println!("{}", val);
}
}
Playpen(也可查看冗长的编译器错误)
不幸的是,这似乎也不起作用。我缺少什么?当你在Vec
上调用.iter()
时,你会得到一个迭代器。因此,当您在Vec
上调用.iter()
时,将得到一个迭代器,而不是迭代器。您应该查看迭代器的.clone()
方法,它应该有助于解决您的问题
另外,请注意,为了遍历迭代器,您必须能够对其进行变异(拥有迭代器或具有对它的可变引用)。所以,对它有一个不可变的引用是有点无用的。我建议将迭代器值移动到print_字符串中,而不是通过引用传递它。如果您想使用trait对象来实现这一点,可以使用Box
,但只需将print\u字符串设置为一个通用函数就可以了。
因此,第一件事是您期望的是Iterator
,但实际上它是Iterator
。
然后,您尝试调用.iter()
,但是迭代器
没有此方法。
您可以简单地删除.iter()
调用并接收(和发送ofc)&mut迭代器
,以获得for
循环工作(for
循环需要一些东西,实现IntoIterator
,而&mut迭代器
就是这个东西)。
添加生命周期,您就可以全部就绪了!:)
另外,我建议使用静态分派。您可以在我提供的示例中看到它。您可以做得更好
fn print_strings<Iterable>(strings: Iterable)
where Iterable: IntoIterator,
Iterable::Item: AsRef<str>
{
for val in strings {
println!("{}", val.as_ref());
}
}
请包含错误消息。它告诉您的实现有什么问题。您可能需要查看迭代器的类型:Iterator::Item
。我认为这不是一个好主意,因为它相当长。您可以单击playpen链接查看整个编译器错误输出。当您在Vec
上调用.iter()
时,您会得到一个迭代器。因此,当您在Vec
上调用.iter()
时,将得到一个迭代器,而不是迭代器。您应该查看迭代器的.cloned()
方法,它应该有助于解决您的问题。另外,请注意,为了在迭代器中进行迭代,您必须能够对其进行变异(拥有迭代器或具有对迭代器的可变引用)。所以,对它有一个不可变的引用是有点无用的。我建议将迭代器值移动到print\u strings
中,而不是通过引用传递它。如果您想使用trait对象来实现此目的,可以使用Box
,但只需将print\u strings
设置为通用函数可能会更容易。顺便说一句,这里有一个版本的代码可以工作:好的,那支playpen会将其完全清除。关于静态分派,我为示例保存了一些击键:P
fn print_strings<Iterable>(strings: Iterable)
where Iterable: IntoIterator,
Iterable::Item: AsRef<str>
{
for val in strings {
println!("{}", val.as_ref());
}
}
print_strings(&strings);
print_strings(strings.iter().map(|s| s.to_owned()));
print_strings(vec![&&&&"xyz"]);
print_strings(strings);
print_strings(more_strings.values());