Suppose we have this piece of code:
type User struct {
int32
Name string
}
Can this type of embedding be useful?
Does int
The type int32
is a predeclared type, it has no methods. To verify:
fmt.Println(reflect.TypeOf(int32(0)).NumMethod()) // Prints 0
You can refer to all embedded fields by using the unqualified type name as the field name (Spec: Struct types), predeclared types are no exception. See this example:
u := User{3, "Bob"}
fmt.Printf("%#v\n", u)
u.int32 = 4
fmt.Println(u.int32)
Output (try it on the Go Playground):
main.User{int32:3, Name:"Bob"}
4
Primary gain of using embedding is:
methods of the embedded type get promoted, so it's easier to implement interfaces (you don't need to provide methods that get promoted)
you can "override" methods of the embedded type (on the embedder type): provide your own implementation which will be called when a value of your embedder type is used
and fields of the embedded type get promoted, so code is shorter to refer to promoted fields (field name is left out).
By embedding predeclared types such as int32
, you don't get any advantage over using just a regular field (named, not embedded field), as the int32
type doesn't have any methods or fields.
Going forward, besides not having any advantage, you even have a disadvantage. Since predeclared type names start with lowercased letters, embedding them implicitly makes them unexported, so you can only refer to them in the declaring package of the embedder type. If you make them regular, named fields, you may choose to use an uppercased name to make it exported, or a lowercased name to make it unexported.