取消引用 Rust 中的引用向量

Derefence a vector of references in Rust

如果我有一个引用向量,我可以这样做:

references.into_iter().map(|x| *x).collect::<Vec<_>>();

有速记吗?使用类似 hoogle 的搜索引擎很容易回答这个问题,但我找不到用于 Rust 的搜索引擎。

相关的,我也很好奇是否有相反操作的shorthand:

objects.iter().collect::<Vec<_>>()

您可以创建一个特征,在 Vecs 上提供一个方便的方法来为您执行此功能:

trait CloneRefs<T> {
    fn clone_refs(&self) -> Vec<T>;
}

impl<T> CloneRefs<T> for [&T] where T: Clone {
    fn clone_refs(&self) -> Vec<T> {
        self.into_iter().map(|&x| x.clone()).collect()
    }
}

fn main() {
    let refs = vec![&1, &2, &3];
    let owned = refs.clone_refs(); // compiles
}

playground

注意:由于 Copy 特征需要 Clone,以上内容适用于所有 CloneCopy 类型。

可能没有完全您想要的操作。您可以 clone() 向量,但这只会给您另一个具有相同引用的向量。如果你想转换向量元素,你应该用迭代器接口来做,因为毕竟你可能不想将结果保存到向量中。如果您确实想要向量中的结果 - 那么,这就是 collect() 的用途。

综上所述,这里有一些方法可以缩短它:

  • 您可以将 map(|x| *x) 替换为 copied()
  • 如果您 return 从函数中获取向量,则不需要显式 ::<Vec<_>> “turbofish”,因为函数将拼写出 return 类型, Rust 将能够推断出它。
  • 如果它是函数中的最后一个表达式,您甚至不需要显式 return

结合以上内容,您可以将 return references.into_iter().map(|x| *x).collect::<Vec<_>>(); 替换为 references.into_iter().copied().collect(),这明显更短,但可能不完全是您想要的。

让您摆脱 turbofish 语法的 itertools crate has a method collect_vec

use itertools::Itertools;

references.into_iter().map(|x| *x).collect_vec()

通过类型推断,有时也可以直接使用 collect。不可否认,改进是微乎其微的。