I was learning golang, and as I was going through the chapter that describes Structures, I came across different ways to initialize structures.
p1 := passport{}
var p2 passport
p3 := passport{
Photo: make([]byte, 0, 0),
Name: "Scott",
Surname: "Adam",
DateOfBirth: "Some time",
}
fmt.Printf("%s\n%s\n%s\n", p1, p2, p3)
While these print the values of the structures as
{ }
{ }
{ Scott Adam Some time}
, the following code below prints with an ampersand because it is a reference.
pointerp1 := &p3
fmt.Printf("%s", pointerp1)
pointerp2 := new(passport)
pointerp2.Name = "Anotherscott"
fmt.Printf("%s", pointerp2)
&{ Scott Adam Some time}&{ Anotherscott }
Kindly help me with my doubts.
in the usage
pointerp1 := &p3
,pointerp1
is the reference variable top3
, which holds the actual data. Similarly, what would be the actual variable that holds the data forpointerp2
?What would be the best scenarios to use these different types of initialization?
There is variable that holds the data yet. You can dereference the pointer using
*pointerp2
, and even assign it that to a variable (p2 := pointerp2
), but this variable would be a copy of the data. That is, modifying one no longer affects the other (http://play.golang.org/p/9yRYbyvG8q).new
tends to be less popular, especially with regard to structs. A good discussion of its purpose (hint: it came first) and use cases can be found at https://softwareengineering.stackexchange.com/a/216582.Edit: Also,
p1
is not really a different kind of initialization fromp3
, but instead of assigning a value to any of the type's fields they are initialized to their zero value (""
forstring
,nil
for[]byte
). The same would happen for any omitted fields:In this case,
p4.Photo
andp4.DateOfBirth
would still be zero-valued (nil
and""
respectively). Thepassport{}
case it just one where all the fields are omitted.new
allocates zeroed storage for a new item or type whatever and then returns a pointer to it. I don't think it really matters on if you usenew
vs short variable declaration:= type{}
it's mostly just preferenceAs for
pointer2
, thepointer2
variable holds its own data, when you donew
allocates zeroed storage in memory and returns a pointer to it, so in short, new will return a pointer to whatever you're making that is whypointerp2
returns&{ Anotherscott }
You mainly want to use pointers when you're passing a variable around that you need to modify (but be careful of data races use mutexes or channels If you need to read and write to a variable from different functions)
A common method people use instead of
new
is just short dec a pointer type:blah := &passport{}
blah is now a pointer to type passport
You can see in this playground:
http://play.golang.org/p/9OuM2Kqncq
When passing a pointer, you can modify the original value. When passing a non pointer you can't modify it. That is because in go variables are passed as a copy. So in the
iDontTakeAPointer
function it is receiving a copy of the tester struct then modifying the name field and then returning, which does nothing for us as it is modifying the copy and not the original.All the new keyword does is basically create a instance of the type you want. However instead of returning the plain declaration of the type, it references it and return the acutal memory address of that type in the program process heap.