Rust中的String与&str迭代器比较

7
我想编写一个函数,接受一组标记列表。但是我在使其足够通用以处理两个非常类似的调用时遇到了问题:
let s = String::from("-abc -d --echo");

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

是否有办法写出一个函数签名,既可以接受 split_ascii_whitespace() 方法,也可以接受 args() 方法?

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

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),
        }
    }
}

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

2个回答

10
您可以要求项类型为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()),
        }
    }
}

2
如果你喜欢在参数位置使用impl trait(这是一种口味问题),你也可以将签名写成fn parse(mut it: impl Iterator<Item = impl AsRef<str>>) - user4815162342

1
根据您的使用情况,您可以尝试以下方法:
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,但是你的具体用例可能需要其他可能是自定义的特性来实现。


3
BorrowAsRef非常相似,容易混淆。历史上引入Borrow的原因是哈希映射要求借用值和原始值的HashEqOrd实现保持一致。由于AsRef没有这些额外的要求,需要一个新的特质。虽然在这种情况下这些要求不相关,但我们只想将获得的任何项目类型转换为&str,因此我认为在这里使用AsRef更合适,尽管我承认在这种特定情况下区别有点哲学意味。 - Sven Marnach
1
@SvenMarnach 在你所写的内容中,AsRef<T> 是一个众所周知的习语,在 stdlib 和其他地方有许多用途。例如,AsRef<Path> 用于接受路径,在许多方式下可以创建它们(从字符串、OsStrPathBuf 等),AsRef<OsStr> 用于需要操作系统字符串的事情,例如命令行,等等。AsRef<str> 对于那些遇到过这些的人来说是熟悉的,而 Borrow<str> 则会错误地指示额外的要求。 - user4815162342

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接