Delving into Type Aliasing Complexities
Consider the following code snippet:
package main import ( "fmt" "time" ) type dur struct { time.Duration } type durWithMethods dur type durWithoutMethods time.Duration func main() { var d durWithMethods // works ?? fmt.Println(d.String()) var dWM durWithoutMethods fmt.Println(dWM.String()) // doesn't compile }
One might ponder why the direct alias of time.Duration (durWithoutMethods) doesn't inherit any methods, while the nested type alias (durWithMethods) grants access to them. This confusion stems from a fundamental difference between type definitions and type aliases.
Defining New Types vs. Renaming Existing Ones
In Go, type declarations fall into two categories: type definitions and type aliases. Type definitions birth fresh types by embedding one or more existing types. They inherit methods only from the top-level embedded types, not from nested types.
Type aliases, on the other hand, are mere shorthands that bind new identifiers to existing types. They don't create new types, so the underlying type remains unchanged. Any methods associated with the underlying type will still be readily accessible through either the original name or the alias.
Understanding durWithMethods
The type durWithMethods effectively extends the dur type by embedding it. Since dur embeds time.Duration, it inherits Duration's methods, including String(). Therefore, d.String() in the code works as expected.
Unveiling durWithoutMethods
Unlike durWithMethods, durWithoutMethods is a direct alias of time.Duration. It doesn't extend anything, so it solely consists of the primitive time.Duration type. Methods of time.Duration are not transferred to durWithoutMethods because it's a distinct type with its own separate set of methods. Hence, dWM.String() won't compile.
The above is the detailed content of Why Do Type Aliases in Go Behave Differently When They Inherit from Embedded Types?. For more information, please follow other related articles on the PHP Chinese website!