String 通过Vec<;字符串>;作为迭代器<&';a str>;

String 通过Vec<;字符串>;作为迭代器<&';a str>;,string,reference,iterator,rust,borrowing,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) } 这是正确的

我有一个函数,可以从单词列表中随机选取单词:

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

这是正确的方法吗?我可以在不显式映射单词列表以获取引用的情况下编写此函数吗?

您可以将泛型函数更改为获取任何可以转换为
&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)
}
pub fn随机词
哪里

I:IntoIterator处理引用比获取完整的
字符串
可能更有效,也可能没有;其实更多的是关于如何使用字符串。如果您稍后将
&str
转换为
字符串
,并丢弃
Vec
,则最好直接对
字符串
进行采样。如果您确实需要对项目的引用,我可能会编写与您类似的代码:
rand::sample(rng,words.iter().map(AsRef::as_ref),4)
。如果您的
random_words
没有做任何有用的事情,您应该直接使用
rand::sample
。那么实现会是什么样子呢?我尝试了各种方法,但我无法通过借用检查器获得问题中的任何正文变体。您是否尝试过类似于
rand::sample(rng,words.map(AsRef::as_ref),n)
?不幸的是,这是一个类型错误。很抱歉,我对生锈还不太熟悉,需要很多人把手拿着不动。是的,问题是
Item
也需要作为参考。我与
rand::sample
call一起更新了代码,非常感谢!它建立起来了,现在给我两天时间来了解发生了什么;)
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);