User Tools

Site Tools


variable_models_in_go

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Next revision Both sides next revision
variable_models_in_go [2017/12/31 06:35]
luciano created
variable_models_in_go [2018/01/18 16:13]
luciano
Line 1: Line 1:
 ====== Variable models in Go ====== ====== Variable models in Go ======
  
-One of the trickiest things to understand in Go is that it has three variable models: values, references, and pointers. In contrast, Java has two (values and references) ​and popular ​dynamic languages -- Python, Ruby, Javascript -- have only one: references.+Go has three variable models: values, references, and pointers. In contrast, Java has two (values and references). Popular ​dynamic languages -- Python, Ruby, Javascript -- have only one: references.
  
-The problem is compounded by the fact that there is no syntactic cue to distinguish values and references ​in Go. Pointer variable declarations are explicit thanks to the ''​*''​ symbol. In Java, reference types are always written with an initial upper caselike ''​String''​.+That was surprising to me at first. My confusion was compounded by the fact that Go has no syntax or convention ​to distinguish values and references. Pointer variable declarations are explicit thanks to the ''​*''​ symbol. In Java, reference types are always written with an initial upper case -- like ''​String'' ​-- and value types such as ''​int''​ are named with lowercase only. 
 + 
 +In Go there are no visual clues: you have to know and remember that variables of special types like ''​map'',​ ''​chan'',​ and //slices// of any type behave as references((''​string''​ variables are also references in Go, but this never causes problems because strings are immutable in Go.)). Problems happen, for example, when you pass a slice to a function and that function changes the content of your slice when you were not expecting it.
  
-In Go there are no visual clues: you have to know and remember that variables of built-in types like ''​string'',​ ''​map'',​ ''​chan''​ and //slices// behave as references. 
  
 ===== But isn't Go all about values? ​ ===== ===== But isn't Go all about values? ​ =====
  
-In a way, yesIf you have an array with 1 million elements and you pass that array to a function directly (without using a pointer), ​the entire array with 1 million elements will be copied to the parameter variable, which is a local variable in the function.+YesBut what are the values?
  
-However, if you pass a slice to a function, the elements ​are copied. The value that is copied is a hidden struct describing ​the sliceIt has three fields:+If you have an array with 1 million elements and you pass that array to a function ​directly (without using a pointer), the entire array with 1 million ​elements ​will be copied ​to the parameter variable, which is a local variable in the function. A variable of any array type holds all the elements of the array, just like a simple '​int'​ variable holds the bits of the integer
  
-  * pointer ​to the first element; +However, if you pass slice to a function, ​the elements are not copied. The value of slice is a hidden struct describing itThat struct has three fields:
-  * an ''​int''​ holding the current length ​of the slice+
-  * an ''​int''​ holding the capacity -- the maximum number of elements the slice can contain.+
  
-This has two very important consequences:​+  - a pointer to the first element; 
 +  - an ''​int''​ holding the current length of the slice; 
 +  - an ''​int''​ holding the capacity -- the maximum number of elements the slice can contain. 
 + 
 +So the only data copied when you pass a slice to a function is that 3-field struct. ​This has two very important consequences:​
  
   - Passing a slice to a function is efficient, regardless of the length of the slice.   - Passing a slice to a function is efficient, regardless of the length of the slice.
   - The function can change the slice at will, and the effects will be seen by the caller.   - The function can change the slice at will, and the effects will be seen by the caller.
  
-Other types like ''​map'',​ ''​chan''​ and ''​string''​ are also represented by implicit structs containing pointers. The ''​string''​ type is immutable, so the fact that its handled like a reference variable is a harmless optimization. But maps and channels are mutable, so the caveats I mentioned for slices also apply: always keep in mind that passing one of those to a function means the function will be able to modify the referenced value, whether you want it or not. +Other types like ''​map'',​ ''​chan''​ and ''​string''​ are also represented by implicit structs containing pointers. The ''​string''​ type is immutable, so the fact that its handled like a reference variable is a harmless optimization. But maps and channels are mutable, so the caveats I mentioned for slices also apply: always keep in mind that passing one of those to a function means the function will be able to modify the referenced value, whether you want it or not
 + 
 +In the case of a channel, we naturally expect it will be consumed or fed by the function. For maps and slices, that is not the case, and subtle bugs may happen if a function is unexpectedly changing the data we pass to it. 
 + 
 +It is interesting to note that slices, maps and channels are built using the ''​make''​ function, which is one of the few generic functions in Go: it takes types as arguments. This is one example of //magic// in the language: mortal Go users are not able to create generic functions, but the Go creators can. Also, mortal Go users are not able to create other types that use implicit reference variables. Variables of user defined types will always be either value variables (holding the actual bytes of the struct) or pointers to them.
  
  
 ===== References ===== ===== References =====
  
-[[See [[https://​blog.golang.org/​go-slices-usage-and-internals|Go Slices: usage and internals]] ​+  ​* [[https://​blog.golang.org/​go-slices-usage-and-internals|Go Slices: usage and internals]]: by Andrew Gerrand in the official Go Blog.  
 +  * [[https://​www.goinggo.net/​2013/​08/​understanding-slices-in-go-programming.html|Understanding slices]]: by Bill Kennedy, showing ''​unsafe''​ inspection of slice values. 
 +  * [[https://​www.calhoun.io/​why-are-slices-sometimes-altered-when-passed-by-value-in-go/​|Why are slices sometimes altered when passed by value in Go?]] by John Calhoun.
  
 +===== Ping back =====
  
 +> If you like what you just read, please share it!
 +> For comments or suggestions,​ please ping me on Twitter: [[https://​twitter.com/​standupdev/​|@standupdev]].
  
  
 +{{tag>​golang programming_language reference_variables}}
  
-{{tag>​golang programming_language}}+~~DISQUS~~
variable_models_in_go.txt · Last modified: 2018/02/24 12:23 by luciano