5 ms·
> It's pass-by-reference 101. Is it though? Slices seem to be passed by value, where the value is a pointer and some bookkeeping information (like a C struct o
by jjnoakes 8y ago
> It's pass-by-reference 101.
Is it though? Slices seem to be passed by value, where the value is a pointer and some bookkeeping information (like a C struct of (data, len, capacity)).
Some operations manipulate just data (which is visible in the caller, since that 1/3 of the "struct" was a pointer passed by value) and some operations manipulate len and/or capacity (which is not visible in the caller, since that 2/3 of the "struct" was also passed by value).
Seems more complex than just hand-waving the details away with "pass-by-reference 101".
- lann 8y agoAn illustation of append being confusing: https://play.golang.org/p/WGwp2cM6E1B https://play.golang.org/p/WGwp2cM6E1B
- deleted 8y ago[deleted]
- scarejunba 8y agoThis would have been a way better WAT.
- adwhit 8y agoIndeed, less 'confusing' and more 'broken'.
- kbenson 8y agoIt's pass by reference 101 where by reference is actually passing a struct by value, and the struct has a reference to more data, so sometimes the backing data is updated and the struct isn't... So, probably more like pass-by-reference-and-by-value 201.
- andrewstuart2 8y agoGo is only pass by value. Much in the same way JavaScript is (the best description for JS, IMO, is reference by value). Even if you pass a pointer, the pointer is explicitly copied to a new location in memory, which is why assignment to the pointer can overwrite the pointer, but not affect the original pointer (the memory location value inside the pointer-typed variable) outside the function scope. Pass by reference is when assignment to a parameter name is transitive to the caller's scope, and can be seen in C#. [1] [1] https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
- int_19h 8y agoNow that C# has ref locals, it's not really pass-by-reference so much so as C++-style (or Algol-68 style, if you go far enough) references that are implicitly dereferenced on access and cannot be rebound.
- hooluupog 8y agoGo is not really 'pass by value' when passing slices. It just passes the pointer value instead of doing a deep copy(copying the backing array). When trying to grow a slice in a function, the result is unpredicted because of 'apend' implicitly choosing to allocate memory or not. In addition, it is not concurrent-safe to pass mutable data. To avoid the safety problem, you have to copy stuff and consequently suffer a performance penalty. A better way to solve the problem is to introduce immutibilty. If one day immutibilty is introduced in Go 2(or 3), i wish slices are really passed by value. Then everything is passed by value as default with the immutable data passed by reference. You can still use pointers to pass mutable data just like using '_' to explicitly ignore error handling. Now in WAT 1, func grow(s []int) { // s is deep copied. s = append(s, 4, 5, 6) // changing 's' does not effect original slice. } Explicitly pass mutable slice, func grow(s *[]int) { // s is referenced. *s = append(*s, 4, 5, 6) // changing 's' will always effect origin slice. } Explicit is better than implicit.
- sacado2 8y agoIn the given examples, it is. But I agree slices are complex in Go, probably the most complex thing for newcommers, and the main reason why I wouldn't recommend go as a first language.