Apitronix
Apitronix

Reputation: 273

Pass mut reference to a function, and get it back

I try to write a code sample since an hour, who add some spaces in a String. So the main borrow a String to a function who add spaces, and then ,I wanna get the string back in the main function.

fn main() {
    ...
    let mut line = String::new();
    line = make_spaces(5, &mut line);
}

fn make_spaces(number: u8, string: &mut String) -> &mut String {
    for _ in 0..number {
        string.push(' ');
    }
    string
}

But the borrow checker give me the following error :

error[E0308]: mismatched types
  --> src/main.rs:14:12
   |
14 |     line = make_spaces(left_spaces, &mut line);
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |            |
   |            expected struct `String`, found `&mut String`
   |            help: try using a conversion method: `make_spaces(left_spaces, &mut line).to_string()`


I'm new with rust, and I know I don't understand borrowing. But I searched the net, and I don't understand it any better.

As I understand, I give the line ownership to make_spaces function, and then I (try to) give the ownership of string back to the main function.


Could you tell me where I'm wrong what is the solution of this problem please ? I know it's a common issue, but I don't see anything simple about that on stackoverflow.

Upvotes: 3

Views: 4691

Answers (2)

Jmb
Jmb

Reputation: 23319

There are two ways to do what you're trying, but you're mixing the two:

Take a mutable parameter as a reference

fn main() {
    let mut line = String::new();
    make_spaces(5, &mut line);
}

fn make_spaces(number: u8, string: &mut String) {
    for _ in 0..number {
        string.push(' ');
    }
}

In that case, the caller gives you a reference to a struct so that you can modify it in place. There is no need to return anything.

Move the parameter into the function, then return the modified value

fn main() {
    let mut line = String::new();
    line = make_spaces(5, line);
}

fn make_spaces(number: u8, mut string: String) -> String {
    for _ in 0..number {
        string.push(' ');
    }
    string
}

In that case, the string is moved into the make_spaces function, so you need to move it back to the caller by returning it.

Upvotes: 11

Denys Séguret
Denys Séguret

Reputation: 382150

You don't have to return anything: you received a reference to a struct the caller of the function already has.

Just do

fn main() {
    let mut line = String::new();
    make_spaces(5, &mut line);
    // use line here
}

fn make_spaces(number: u8, string: &mut String) {
    for _ in 0..number {
        string.push(' ');
    }
}

Upvotes: 1

Related Questions