Reputation: 541
I will clarify the question a bit. I have read (almost completely) the Go specification, FAQ, Effective Go, and, of course, Tour of Go.
I know that Go is a "pass by value" language and even managed to reason about this behavior and understand all the implications.
All assignments in Go also create copies. In some cases, it's just a value, in some -- a pointer. For some data structures, it's a bit trickier in that the whole structure is copied and might include an implicit pointer to another data structure.
The question is: what in the language specification says explicitly that assignments always create copies?
I feel like it doesn't even need to be mentioned once you understand that there are no references in Go, but the section on assignment statements in the specification doesn't even mention the pass-by-value semantics.
I feel like there must be something in the documentation that describes the behavior in detail, and I, due to lack of some foundational misunderstanding, fail to realize the explanation is there.
Upvotes: 2
Views: 2973
Reputation: 51512
The spec actually explicitly talks about this here:
https://golang.org/ref/spec#Calls
In particular:
After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution. The return parameters of the function are passed by value back to the caller when the function returns.
About assignments: All assignments in most of the languages I know of create copies of values (see Python exception in the comments). A copy of the value on the RHS is assigned to the LHS. If the RHS is a pointer, then a copy of that pointer is assigned to the LHS.
Upvotes: -1
Reputation: 44608
What in the language specification says explicitly that assignment always creates copies?
Nothing explicit, but you can maybe deduce this from Variables, which nicely addresses also the case of function signatures:
A variable declaration or, for function parameters and results, the signature of a function declaration or function literal reserves storage for a named variable.
If storage is reserved, when later you assign the result of a unary expression to it — e.g. another variable —, then it must be a copy, otherwise you would have memory aliasing. Which is what Dave Cheney is talking about in There is no pass-by-reference in Go.
Unlike C++, each variable defined in a Go program occupies a unique memory location.
This also has one more important implication, which is the zero value. If you don't provide an expression to initialize a variable in its declaration, the storage reserved for it is given the zero value as default value.
Upvotes: 3
Reputation: 8395
Without going into too much detail, these excerpts from the spec should provide some clarity:
A variable is a storage location for holding a value.
A variable's value [...] is the most recent value assigned to the variable.
At the language level, defining "copying" of values isn't really necessitated. The important implication of copying as we commonly understand it, is that modifying the "copied to" value will not alter the "copied from" value *. This property can be inferred from the above quotations.
Upvotes: 2