What is the different between anonymous field as pointer or anonymous field as usual. Consider, how I embed Foo into Bar struct.
Look at the following code snippet:
First with anonymous field as pointer
package main
import (
"fmt"
)
type Foo struct{}
func (*Foo) Run() {
fmt.Println("Hello")
}
type Bar struct {
*Foo
}
func main() {
bar := new(Bar)
bar.Run()
}
and second anonymous field as usual:
package main
import (
"fmt"
)
type Foo struct{}
func (*Foo) Run() {
fmt.Println("Hello")
}
type Bar struct {
Foo
}
func main() {
bar := new(Bar)
bar.Run()
}
What is different between them?
Update: I pick up this sample from revel webframework, how they extend a custom controller. Look at this code snippet
type App struct {
*revel.Controller
}
why do revel use pointer to embed controller struct. What is the sense of it?
Given that Foo
is an empty struct, embedding it in Bar
will make no change to to the memory footprint of Bar
.
However, embedding a pointer to Foo
will change Bar
; it will add a pointer value, initialized to nil
. If the only purpose of Foo
is to have methods, then using a pointer is superfluous.
Of course, were you to add some fields into Foo
, then, in the pointer case, you'd also need to add bar.Foo = new(Foo)
into main, or else you'll have problems.
The advantage of using a pointer would be that you could share the same Foo
instance between multiple instances of Bar
, or else you could keep it nil
until you really need it.
The disadvantage would be that it would be slightly more trouble, and slightly less efficient, if there's always a 1-to-1 Foo
-to-Bar
mapping.
As long as it forms valid selector there is no difference in usage except the following ( and the usual tradeoffs of using values vs. pointers ) :
- If x is of pointer type and has the value nil and x.f denotes a struct field, assigning to or evaluating x.f causes a run-time panic.
- If x is of interface type and has the value nil, calling or evaluating the method x.f causes a run-time panic.
and this :
- If S contains an anonymous field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
- If S contains an anonymous field *T, the method sets of S and *S both include promoted methods with receiver T or *T.