0

How can I make this compile:

struct S {
    s:String
}

fn main() {
    let mut v:Vec<S>;
    let cmp = "asdf";
    v.iter_mut().find(|&&x| x == cmp);
    //                 ^^^
    //                 What to write here when using find on a iter_mut (and why?)
}

Error message:

 --> src/main.rs:8:25
  |
8 |     v.iter_mut().find(|&&x| x == cmp);
  |                         ^-
  |                         ||
  |                         |expected due to this
  |                         types differ in mutability
  |                         help: you can probably remove the explicit borrow: `x`
  |
  = note: expected mutable reference `&mut S`
                     found reference `&_`

For more information about this error, try `rustc --explain E0308`.
error: could not compile `asdf` due to previous error
Allan
  • 4,562
  • 8
  • 38
  • 59

1 Answers1

2

You don't have to destructure S in the closure because that would move the String.

struct S {
    s: String,
}

fn main() {
    let mut v: Vec<_> = vec![S { s: "Hello".into() }, S { s: "asdf".into() }];
    let cmp = "asdf";

    // Will be Option<&mut S>
    let _found = v.iter_mut().find(|x| x.s == cmp);
}

I added two items to the Vec since you declared v without defining it. Notice that the closure just takes x which is a &&mut, but you don't have to explicitly say that anywhere because x will be dereferenced in the body of the closure.

The expression x.s == cmp compares the String, s, from to the &str, cmp.

// Automatically dereferenced
x.s == cmp

And manually:

// Manually dereferenced. You don't have to do this for structs.
(**x).s

Further reading

Joshua Megnauth
  • 281
  • 1
  • 7