When should I use a reference instead of transferring ownership?
Asked Answered
P

1

25

From the Rust book's chapter on ownership, non-copyable values can be passed to functions by either transferring ownership or by using a mutable or immutable reference. When you transfer ownership of a value, it can't be used in the original function anymore: you must return it back if you want to. When you pass a reference, you borrow the value and can still use it.

I come from languages where values are immutable by default (Haskell, Idris and the like). As such, I'd probably never think about using references at all. Having the same value in two places looks dangerous (or, at least, awkward) to me. Since references are a feature, there must be a reason to use them.

Are there situations I should force myself to use references? What are those situations and why are they beneficial? Or are they just for convenience and defaulting to passing ownership is fine?

Pterodactyl answered 25/4, 2018 at 17:9 Comment(11)
Having the same value in two places at the same time looks confusing [...] Mutable references in particular look very dangerous. What other programming languages have you used? The vast majority of them implicitly use "mutable references" for most values all the time. Would you consider most languages dangerous?Vicissitude
Speaking of when to own resources and when to borrow them is often a matter of software design, and can arouse various opinions. Like Shepmaster, I also don't understand your confusion with references. Perhaps narrowing the question down to an example would help?How
@Vicissitude yes I would, personally. I come from languages where values are immutable by default (Haskell, Idris and the like). As such, I'd probably never think in using references at all. But they are a feature, so there must be a reason. Thus, what I'm asking is: are there situations I should force myself to use references? What are those situations and why are they beneficial? Or are them just for convenience and defaulting to passing ownership is fine?Pterodactyl
@Stargateur I've edited the question, what do you think?Pterodactyl
"Having the same value in two places looks dangerous (or, at least, awkward) to me." If you're passing the same value to two different functions in a purely functional programming language, the compiler/interpreter will most likely just share it by reference internally, which should still be safe because the value is immutable. Can you better expose your concern towards having multiple immutable references in Rust?How
@How I can't, my main concern is that having a value in many places will make it harder to analyze my own code and understand error messages. Rust isn't immutable like Haskell, I'm not confident that references and mutability mix well and fear it could get unwieldy quickly, whereas transfer of ownership looks more straightforward (a value is only at a single place at the same time). But that's just a guess. If references work fine for you all, then they may work for me. I'll give it a try.Pterodactyl
@Pterodactyl I can only imagine some sort of misconception here. For as long as an immutable reference to a value exists, that value cannot inherently mutate. This should be well explained in the following chapter: References and Borrowing.How
@How no misconception about that, I'm aware the compiler will not me allow to mutate a value with active references. That's neat. I get that. I was not asking if there would be bugs, I was asking if having many references around would lead to cryptic compiler errors and painful hours of debugging. Ownership transfers looked more straightforward at a first glance. But again, I was just asking. Your tone seems to indicate you're pretty happy with using references, so I will try. Experience will tell me how well they work in practice.Pterodactyl
Let us continue this discussion in chat.How
Oddly enough, I found a similar question in the Rust users board. users.rust-lang.org/t/what-is-the-better-code-design/17041How
See also: In what scenarios are APIs that don't borrow preferred?Yippie
Y
22

Mutable references in particular look very dangerous.

They are not dangerous, because the Rust compiler will not let you do anything dangerous. If you have a &mut reference to a value then you cannot simultaneously have any other references to it.

In general you should pass references around. This saves copying memory and should be the default thing you do, unless you have a good reason to do otherwise.

Some good reasons to transfer ownership instead:

  1. When the value's type is small in size, such as bool, u32, etc. It's often better performance to move/copy these values to avoid a level of indirection. Usually these values implement Copy, and actually the compiler may make this optimisation for you automatically. Something it's free to do because of a strong type system and immutability by default!
  2. When the value's current owner is going to go out of scope, you may want to move the value somewhere else to keep it alive.
Yippie answered 25/4, 2018 at 17:20 Comment(3)
My understanding was that passing ownership do not copy any memory too. I was under the impression it should be the default. Is this wrong?Pterodactyl
You can reason about the behaviour of your code as if the value is moved in memory. In practice, the compiler may or may not actually move it.Yippie
Okay, thanks for the inputs. My impression was that using references will make my values live in way too many places simultaneously, making debugging and reasoning about my own code more painful than it should be if I just had them at one place only, always (i.e., passing ownership). I'll take your advice as a more experienced rustacean, though, and experiment with references.Pterodactyl

© 2022 - 2024 — McMap. All rights reserved.