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{}
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 from p3
, but instead of assigning a value to any of the type's fields they are initialized to their zero value (""
for string
, nil
for []byte
). The same would happen for any omitted fields:
p4 := passport{
Name: "Scott",
Surname: "Adam",
}
In this case, p4.Photo
and p4.DateOfBirth
would still be zero-valued (nil
and ""
respectively). The passport{}
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 use new
vs short variable declaration := type{}
it's mostly just preference
As for pointer2
, the pointer2
variable holds its own data, when you do
// initializing a zeroed 'passport in memory'
pointerp2 := new(passport)
// setting the field Name to whatever
pointerp2.Name = "Anotherscott"
new
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 why pointerp2
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.