Rust 字符串与 &str 迭代器

Rust String vs &str iterators

我正在尝试编写一个接受标记列表的函数。但是我在使其足够通用以处理两个非常相似的调用时遇到了问题:

let s = String::from("-abc -d --echo");

parse( s.split_ascii_whitespace() );
parse( std::env::args() );

有没有一种方法可以让我为 parse 编写一个接受这两种方法的函数签名?

我现在的解决方案需要复制函数体:

fn main() {
    let s = String::from("-abc -d --echo");

    parse_args( s.split_ascii_whitespace() );
    parse_env( std::env::args() );
}

fn parse_env<I: Iterator<Item=String>>(mut it: I) {
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}",s),
        }
    }
}

fn parse_args<'a, I: Iterator<Item=&'a str>>(mut it: I) {
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}",s),
        }
    }
}

如果不可能,那么一些关于如何使用特征以便函数可以使用相同名称的建议会很好。

根据您的用例,您可以尝试:

fn main() {
    let s = String::from("-abc -d --echo");

    parse( s.split_ascii_whitespace() );
    parse( std::env::args() );
}

fn parse<T: std::borrow::Borrow<str>, I: Iterator<Item=T>>(mut it: I) {
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}",s.borrow()),
        }
    }
}

我使用 Borrow 作为达到 &str 的方法,但您的具体用例可能由其他(可能是自定义)特征提供服务。

您可以要求项目类型为 AsRef<str>,这将包括 &strString:

fn parse<I>(mut it: I)
where
    I: Iterator,
    I::Item: AsRef<str>,
{
    loop {
        match it.next() {
            None => return,
            Some(s) => println!("{}", s.as_ref()),
        }
    }
}