【问题标题】:How to find an element in vector of Option<String> [duplicate]如何在 Option<String> 的向量中查找元素 [重复]
【发布时间】:2021-05-24 02:46:15
【问题描述】:

作为一个 rust 新手,我在使用“find”函数在 Option 的向量中查找元素时遇到问题:

#[derive(Debug)]
struct MyStruct {
    name: Option<String>,
    data: Option<String>
}

fn main() {
    let my_vec=vec![
        MyStruct{
            name:Some(String::from("name1")),
            data:Some(String::from("data1"))
        },
        MyStruct{
            name:Some(String::from("name2")),
            data:Some(String::from("data2"))
        }
    ];
    let search_string = String::from("name2");
    let found_record=my_vec.iter().find(|s| s.name == Some(search_string));
    println!("{:?}", found_record);
}

由于缺少 Copy 特征,比较 s.name == Some(search_string),此代码无法编译。 “查找”表达式的正确方法是什么?

【问题讨论】:

标签: vector rust find closures


【解决方案1】:

错误原因

请注意,您正在通过移动String 在闭包内使用Some() 来构造Option


一些解决方案

  1. 您可以通过在其前面构造Option 来避免移动并通过不可变引用进行闭包捕获,如下所示
let search_string = Some(String::from("name2"));
let found_record=my_vec.iter().find( |s| s.name == search_string);

  1. 或者在Option里面输入,如下
let search_string = String::from("name2");
let found_record=my_vec.iter().find( 
    |s| match &s.name{Some(name)=> name, _ => return false,} == &search_string
);


我不喜欢这种方法

let found_record = my_vec.iter().find(
  |s| s.name.as_deref() == Some(search_string.as_ref()));

因为它每次迭代都会生成一个新的Some(),除非编译器进行了优化。

【讨论】:

  • @UdoEisenbarth 如果你的意思是第二种情况,不。请注意,第一个匹配臂的结果将是 &amp;String 类型,因为您匹配的是 &amp;Option&lt;String&gt;,而不是 Option&lt;String&gt;
【解决方案2】:

一种选择是将search_string 和结构字段都转换为Option&lt;&amp;str&gt; 以进行比较:

let found_record = my_vec.iter().find(
  |s| s.name.as_deref() == Some(search_string.as_ref()));

playground

【讨论】:

  • 非常感谢。如果我使用Some(&amp;search_string) 而不是建议的Some(search_string.as_ref()),会有区别吗?两个版本都编译并返回正确答案。
  • 它们应该与您的用例等效。只是要注意Some(&amp;search_string) 返回Option&lt;&amp;String&gt; 而后者返回Option&lt;&amp;str&gt;,它们是不同的,但都应该给出正确的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
  • 2017-04-15
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 2019-03-25
  • 1970-01-01
相关资源
最近更新 更多