For nearly two years I am now struggling with the popular Rust phrase
Each value in Rust has an owner.
which occurs in the official tutorial, and in many beginner tutorials and books, typically without a more detailed explanation.
The obvious question for a reader should be: Who is the owner of these "values"? I think typically the owners are variables, or when values are moved into functions or closures, the ownership transfers to the parameters. For string slices and array literals, the owner should be the data segment of the executable binary? Are there more types of possible owners?
And the other issue is: What is a value, and has each value in Rust really an owner? What is with
let a = 1 + 2;
or expressions like
if a > 3 * 4 {
Are the literals 1, 2, 3, 4 values, and have they owners? Have numeric or character constants owners?
Can and should we define what values in Rust actually mean, and should we use the distinction of l- and r-values sometimes uses for other languages?
On that last part, a definite yes, though in Rust we call them value and place instead.
Expressions are divided into two main categories: place expressions and value expressions; […]. The evaluation of an expression depends both on its own category and the context it occurs within.
[…]
Note
Historically, place expressions were called lvalues and value expressions were called rvalues.
Note that the two are not the same. While string slice literals are always surfacing through &'static str, array literals can be assigned to variables by value in which case there is not any data owned by the static data segment involved. The question of what exactly to think of the literal itself here though is similar to your general question of what to make of e.g. numeric literals.[1]
Once you talk about something like &'static str, the language can additionally get confusing because you can additionally consider the slice reference itself also a kind of value in and by itself (i.e. the 2 words of data containing the address and the length), which itself also has an owned, but as for the string data itself (the UTF-8 encoded characters), they are of course only “borrowed”.
Another complication is that owneds can lend out access to what they own, and we don’t really have any words that describe this property, even though it can be quite significant. The ownership that the static data segment has of your string literals is perpetually lent out (in a shared/immutable) manner, which is a qualitative difference from the more narrow meaning of “owned” access to a local variable that might typically imply full, unaliased, mutable access, and additionally even the ability to move out the value.
Another sense of “owner” can often be something like “whoever is responsible for dropping the value”, though you might replace “responsible for …ing” with “able to …” here.
For the case of the static data, these possible senses of ownership might be not fitting very well, because with a perpetually-lent-out kind of data, there is no possibility for ever dropping the data; nor any responsibility, either.[2]
A literal expression is a way of creating a value. It’s a value expression, and once evaluated it sits in some variable - often a temporary variable [aka a “temporary” ([1], [2], [3])] - which then is the owner for some time, until the value is ultimately dropped [for the “normal” temporaries of “value expression used in place expression context”] or transferred somewhere else [for the other kind of temporaries that hold operands of expressions while other operands are still being evaluated].
I might intend to improve my own Rust book a bit this winter, and this phrase, which I have used in a similar way, is one of the ugly parts in my opinion. (But perhaps I will buy and read the book of Jon Gjengset instead, or do something completely different.)
I also think literals are very close to constants. Like those, the literal itself, or the const itself, does not have any owner, because it doesn’t physically exist anywhere a run-time. But an expression like 123, or like FOO (for a const FOO: … = …; defined somewhere else) is a value expression that evaluates by setting[1] the immediate (shallow) bytes of the to-be-owner variable (or other memory location) to a specific compile-time-known constant value.
For an example case of “other memory location”, I don’t believe evaluation of something like *foo = FOO; or *bar = 123;[for foo/bar being something like &mut T or Box<T>, with const FOO: T = …, or T a numeric type, respectively] involves any additional intermediate place that ever owns any value, the compile-time-known byte pattern is just directly written to the destination.
In my option owners is anything what has obligation to free memory, because only owner can free memory in rust, this means everything in rust have owner, or here would be memory leak.
Variable is only name for memory address where data is stored. But not all addresses needs to have variables for names. In case of this
let s: &str = "Some string";
Owner will be some anonimouse addrsess and this address will free memory this string takes after application are stoped, because application binary is owner of this value. Variable s only borrows reference to this value.
In case of let a = 1 + 2;
Here will not be values of 1 and 2, because compiler will optimize and add them into 3, and because 3 is int it will be just put into memory of variable a.
Value will be 3 and owner will be memory address where value is put and 'a' in this case is nickname of this memory address.
In my view, one could think along these lines (it's just an idea):
Take: let a = "hello". We can just say a owns that value (or any other value.) so anything that could go on RHS is a value. (not in the most technical sense, but in a helpful sense.)
Most relevant: Is a: Copy or not?
Will a be usable after this operation let b = a?
Will it be after move to a closure?
Which values would make a unusable after the operation?
So we have values (RHS) and owners (variables) and what happens when we use them.
The question of where it is stored becomes less important for a beginner.
One can still mention the levels: binary vs stack vs heap but except to explain a few key behaviours this rarely matters?
Some will still ask: why is String moved? We can say "it is not Copy". Some will insist: Why isn't it Copy? And I'm not even sure we need to go into too much detail here, except that it's more expensive, so it requires using .clone ?
PS: maybe another useful point is that *a can also be assigned to, but not &a. This would require explain place expression vs value expression.
I think the only way to have a strict answer to this would be to look at MIR instead. At that level, if you have 1 + 2 + 3 there's a temporary place into which the 1 + 2 value is written, then there's a move(temp) + 3 which is written into another place.
And you can see from Operand in rustc_middle::mir - Rust that certain constants just don't have an owner, because they're used directly, rather than ever being in a place.