Golang struct initialization
The first method
e1 := Event{Id: 1, Name: "event 1"}
is initializing the variable e1
as a value with type Event
.
The second
e2 := &Event{Id: 1, Name: "event1"}
is initializing e2
as a pointer to a value of type Event
As you stated in the comments, the set of methods defined on a value of a given type are a subset of the set of methods defined on a pointer to a value of that type. This means that if you have a method
func (e Event) GetName() string {
return e.Name
}
then both e1
and e2
can call this method, but if you had another method, say:
func (e *Event) ChangeName(s string) {
e.Name = s
}
Then e1
is not able to use the ChangeName
method, while e2
is.
This (e1
is not able to use the ChangeName
method, while e2
is) is not the case (although it may have been at the time of writing for this help), thanks to @DannyChen for bringing this up and @GilbertNwaiwu for testing and posting in the comments below.
(To address the striked out section above: The set of methods defined on a struct type consist of the methods defined for the type and pointers to the type.
Instead, Go now automatically dereferences the argument to a method, so that if a method receives a pointer, Go calls the method on a pointer to that struct, and if the method receives a value, Go calls the method on the value pointed to by that struct. At this point my attempt to update this answer may be missing something important in semantics so if someone would like to correct this or clarify feel free to add a comment pointing to a more comprehensive answer. Here is a bit from the go playground illustrating this issue: https://play.golang.org/p/JcD0izXZGz.
To some extent, this change in how pointers and values work as arguments to methods defined on function affects some areas of the discourse below but I will leave the rest unedited unless someone encourages me to update it as it seems to be more or less correct within the context of general semantics of languages that pass by value vs. pointer.)
As to the difference between pointers and values, this example is illustrative, as pointers are ordinarily used in Go to allow you to mutate the values a variable is pointing to (but there are many more reasons one might use pointers as well! Although for typical use, this is normally a solid assumption). Thus, if you defined ChangeName
instead as:
func (e Event) ChangeName(s string) {
e.Name = s
}
This function would not be very useful if called on the value receiver, as values (not pointers) won't keep changes that are made to them if they're passed into a function. This has to do with an area of language design around how variables are assigned and passed: What's the difference between passing by reference vs. passing by value?
You can see this on this example in the Go Playground: https://play.golang.org/p/j7yxvu3Fe6
The type of e1
is Event
the type of e2
is *Event
. The initialization is actually the same (using composite literal syntax, also not sure if that jargon is Go or C# or both?) but with e2
you using the 'address of operator' &
so it returns a pointer to that object rather than the instance itself.