如何使用Iterator特征构建通用API

Chr*_*oph 6 collections iterator traits rust

我可能没有看到森林的树木,但我想知道我如何设计我的方法,以对抗硬集合类型,而不是反对迭代器.考虑这种方法.

pub fn print_strings(strings: Vec<String>) {
    for val in strings.iter() {
        println!("{}", val);
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,如果我想用一个HashSet或那个来使用它,这就不足了HashMap.

所以,我试过这个:

use std::collections::*;

fn main () {
    let strings = vec!("Foo", "Bar");

    let mut more_strings = HashMap::new();
    more_strings.insert("foo", "bar");
    more_strings.insert("bar", "foo");

    print_strings(&strings.iter());
    print_strings(&more_strings.values())
}

fn print_strings(strings: &Iterator<Item=&str>) {
    for val in strings {
        println!("{}", val);
    }
}
Run Code Online (Sandbox Code Playgroud)

游戏围栏(也用于查看冗长的编译器错误)

http://is.gd/EYIK11

不幸的是,这似乎也没有做到这一点.我错过了什么?

Vee*_*rac 7

更好的是,你可以做到

fn print_strings<Iterable>(strings: Iterable)
    where Iterable: IntoIterator,
          Iterable::Item: AsRef<str>
{
    for val in strings {
        println!("{}", val.as_ref());
    }
}
Run Code Online (Sandbox Code Playgroud)

(Kudos Shepmaster的改进.)

这意味着您可以使用&mut Iterators进行动态调度具体迭代器或静态分派的集合类型.此外,迭代器类型可以是可以简单地转换为的任何东西,&str包括但不限于&str,&&str甚至String.

print_strings(&strings);
print_strings(strings.iter().map(|s| s.to_owned()));
print_strings(vec![&&&&"xyz"]);
print_strings(strings);
print_strings(more_strings.values());
Run Code Online (Sandbox Code Playgroud)