1

Here is my code, and the compiler error beneath.

fn main() {
    let mut s = String::new();
    let mut push_if = |b, some_str| {
        if b {
            s.push_str(some_str);
        }
    };
    push_if(s.is_empty(), "Foo");
    println!("{}", s);
}
error[E0502]: cannot borrow `s` as immutable because it is also borrowed as mutable
 --> src/main.rs:8:13
  |
3 |     let mut push_if = |b, some_str| {
  |                       ------------- mutable borrow occurs here
4 |         if b {
5 |             s.push_str(some_str);
  |             - first borrow occurs due to use of `s` in closure
...
8 |     push_if(s.is_empty(), "Foo");
  |     ------- ^ immutable borrow occurs here
  |     |
  |     mutable borrow later used by call

Why is the compiler complaining about s.is_empty() being an immutable borrow? I'm just trying to return a bool, which doesn't seem like I'm borrowing anything. What changes do I need to make to compile the program successfully?

jmrah
  • 5,715
  • 3
  • 30
  • 37
  • It looks like your question might be answered by the answers of [Can't borrow mutably within two different closures in the same scope](https://stackoverflow.com/q/49703990/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Nov 06 '19 at 01:25
  • I will take a look at that answer and get back. Thanks. – jmrah Nov 06 '19 at 01:30
  • I had a look at the linked question Shepmaster, and tbh, for a Rust new-born like me, I found it hard to grok, and couldn't apply the insight from that question to this one. I'm no further in understanding why my code won't compile :(. – jmrah Nov 06 '19 at 01:54
  • How about [How do I modify a variable that's defined outside of a closure from inside of a closure?](https://stackoverflow.com/q/38423607/155423) or [Rust Inspect Iterator: cannot borrow `*` as immutable because it is also borrowed as mutable](https://stackoverflow.com/q/36511683/155423) – Shepmaster Nov 06 '19 at 02:24
  • The [answer posted](https://stackoverflow.com/a/58721953/155423) is an application of [the first solution I linked](https://stackoverflow.com/a/49709386/155423) ('"promote" the data to an argument of the function and the closures'). – Shepmaster Nov 06 '19 at 02:25

1 Answers1

0

You can try this:

fn main() {
    let mut s = String::new();

    let mut push_if = |b, some_str, string: &mut String| {
        if b {
            string.push_str(some_str);
        }
    };

    push_if(s.is_empty(), "Foo", &mut s);
    println!("{}", s);
}
Dino
  • 7,779
  • 12
  • 46
  • 85
D.8Ge
  • 39
  • 6