将Vec <string>作为IntoIterator传递&lt;&amp;&#39; str&gt;

时间:2016-02-25 11:34:33

标签: string reference iterator rust borrowing

我有一个应该从单词列表中选择随机单词的函数:

pub fn random_words<'a, I, R>(rng: &mut R, n: usize, words: I) -> Vec<&'a str>
where
    I: IntoIterator<Item = &'a str>,
    R: rand::Rng,
{
    rand::sample(rng, words.into_iter(), n)
}

据推测,这是一个合理的签名:由于我在函数中实际上并不需要字符串本身,因此处理引用比获取完整String更有效。

如何优雅高效地将Vec<String>与我的程序从文件中读取的单词传递给此函数?我得到了这个:

extern crate rand;

fn main() {
    let mut rng = rand::thread_rng();
    let wordlist: Vec<String> = vec!["a".to_string(), "b".to_string()];

    let words = random_words(&mut rng, 4, wordlist.iter().map(|s| s.as_ref()));
}

这是正确的方法吗?我是否可以在没有明确映射单词列表的情况下编写它以获得引用?

1 个答案:

答案 0 :(得分:6)

您可以更改通用函数以将任何可以转换为&str的函数,而不是让它采用产生&str的迭代器:

pub fn random_words<'a, I, R, J>(rng: &mut R, n: usize, words: I) -> Vec<&'a str>
where
    I: IntoIterator<Item = &'a J>,
    J: AsRef<str> + 'a,
    R: rand::Rng,
{
    rand::sample(rng, words.into_iter().map(AsRef::as_ref), n)
}
let words: Vec<&str> = random_words(&mut rng, 4, &wordlist);

The Book even has an entire chapter devoted to this topic