rust 将连接过滤器和Map放在同一行代码中

py49o6xq  于 2023-02-16  发布在  其他
关注(0)|答案(2)|浏览(117)

我想改变对象向量的特定属性的值。
我的代码和逻辑如下:

let mut person_found: Vec<Person> = persons.clone().into_iter().filter(|x| x.id == "3")
                       .map(|x| x.name = "Carlos".to_string()).collect();

println!("original: {:?}", &persons);
println!("modified person: {:?}", &person_found);

但它给了我以下错误,我不能很好地理解它。

error[E0277]: a value of type `Vec<Person>` cannot be built from an iterator over elements of type `()`
  --> src\main.rs:17:45
   |
17 |     .map(|x| x.name = "Carlos".to_string()).collect();
   |                                             ^^^^^^^ value of type `Vec<Person>` cannot be built from `std::iter::Iterator<Item=()>`
   |
   = help: the trait `FromIterator<()>` is not implemented for `Vec<Person>`
r7xajy2e

r7xajy2e1#

赋值的结果是() (the unit value),所以如果你做y = (x = 123);,那么x被赋值为123y被赋值为()
rust 参考有一个简短的句子,说明:
赋值表达式总是生成the unit value

  • 赋值表达式-运算符表达式-Rust参考
    你需要修改一下,这样它就可以在下一行显式地返回x,如果你想修改x,那么你也需要把|x|修改为|mut x|
let person_found: Vec<Person> = persons
    .clone()
    .into_iter()
    .filter(|x| x.id == "3")
    .map(|mut x| {
        x.name = "Carlos".to_string();
        x
    })
    .collect();

或者,我不是预先克隆整个personsVec,而是在map()中的filter()clone()之后使用cloned(),即仅在需要时使用。

let person_found: Vec<Person> = persons
    .iter()
    .filter(|x| x.id == "3")
    .cloned()
    .map(|mut x| {
        x.name = "Carlos".to_string();
        x
    })
    .collect();
yhxst69z

yhxst69z2#

在map expr行中没有返回任何内容。但是可以使用filter_map进行处理:

let mut person_found: Vec<Person> = persons
    .iter()
    .filter_map(|p| 
                (p.id == 3).then_some(Person {
                                     name: String::from("Carlos"),
                                     ..p.clone()}))
    .collect();

Playground

相关问题