Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between borrowing an argument as mutable and taking ownership of it and returning it?

Tags:

rust

Consider:

fn main() {
    let mut words: Vec<String> = Vec::new();
    words.push(String::from("Example1"));
    do_something(&mut words);

    for word in words.iter() {
        println!("{}", word);
    }
}

fn do_something(words: &mut Vec<String>) {
    //modify vector, maybe push something:
    words.push(String::from("Example2"));
}

vs.

fn main() {
    let mut words: Vec<String> = Vec::new();
    words.push(String::from("Example1"));
    words = do_something(words);

    for word in words.iter() {
        println!("{}", word);
    }
}

fn do_something(mut words: Vec<String>) -> Vec<String> {
    //modify vector, maybe push something:
    words.push(String::from("Example2"));
    return words;
}

Both solutions will print:

Example1
Example2

Is there any difference? What should we use?

like image 217
anghenfil Avatar asked Sep 18 '25 23:09

anghenfil


1 Answers

No, there's really not much difference in the capability of code using one or the other.

Most of the benefits of one vs the other lie outside of pure capability:

Taking a reference is often more ergonomic to the users of your code: they don't have to continue to remember to assign the return value of each function call.

Taking a value vs. a reference is also often a better signal to your user about the intended usage of the code.

There's a hierarchy of what types are interoperable. If you have ownership of a value, you can call a function that takes ownership, a mutable reference, or an immutable reference. If you have a mutable reference, you can call a function that takes a mutable reference or an immutable reference. If you have an immutable reference, you can only call a function that takes an immutable reference. Thus it's common to accept the most permissive type you can.

like image 141
Shepmaster Avatar answered Sep 20 '25 15:09

Shepmaster