如何在使用iter()。filter()。collect()而不是Vec <&& String>之后获取Vec <&String>

时间:2019-02-06 11:58:30

标签: vector reference rust iterator

我有一个字符串向量。我想从这个向量中得到两个子集: 带有cubeview的字符串和带有"zzz"的字符串。

每个子集的类型为"bye"。这是对原始String的引用的引用向量。我怎么能只得到Vec< && String>

我当前正在处理的代码:

Vec<& String>

Playground

一种方法是使用use std::string::String; use std::vec::Vec; fn main() { let a1 = String::from("hi"); let a2 = String::from("bye"); let a3 = String::from("zzz"); let v_before: Vec<&String> = vec![&a1, &a2, &a3]; // ref_a is a copy of v_before[0] let ref_zzz_a: &String = v_before[2]; let ref_zzz_b: &String = v_before[2]; println!("before: {:?}", v_before); // QUESTION: why can not this also be Vec<& String> ? // v_zzz is just like making vec![ref_zzz_a, ref_zzz_b] let v_zzz: Vec<&&String> = v_before .iter() .filter(|&&element| element.contains("zzz")) .collect(); let v_bye: Vec<&&String> = v_before .iter() .filter(|&&element| element.contains("bye")) .collect(); let hand_made: Vec<&String> = vec![ref_zzz_a, ref_zzz_b]; println!("v_zzz: {:?}", v_zzz); println!("v_bye: {:?}", v_bye); println!("hand_made: {:?}", hand_made); } ,但随后我将无法运行第二个过滤器。

也许这仅仅是生锈的方法?由于自动取消引用,也许我应该不在乎这是vector.into_iter()...吗?以后会导致问题吗?

1 个答案:

答案 0 :(得分:7)

您可以使用Iterator::cloned克隆每个引用,而不必再次引用它们:

let v_zzz: Vec<&String> = v_before
    .iter()
    .filter(|&element| element.contains("zzz"))
    .cloned()
    .collect();

克隆引用很便宜,因为它是implemented by dereferencing


放在一边:通常最好绕过&str而不是&String,因为它更灵活。当我在Rust代码中看到&String时,它可能是不希望的或可以改进的东西。