We’ve made it through the complete list of types in Go. Now we’re going to dig into some of the fundamentals, with a tour of general “Properties of types and values”.
Properties of types and values
Underlying types
Each type
Thas an underlying type: IfTis one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type isTitself. Otherwise,T’s underlying type is the underlying type of the type to whichTrefers in its declaration. For a type parameter that is the underlying type of its type constraint, which is always an interface.type ( A1 = string A2 = A1 ) type ( B1 string B2 B1 B3 []B1 B4 B3 ) func f[P any](x P) { … }The underlying type of
string,A1,A2,B1, andB2isstring. The underlying type of[]B1,B3, andB4is[]B1. The underlying type ofPisinterface{}.
So this all seems pretty straight forward. But who cares?
The underlying type is used in type conversions, which we’ll cover in greater detail later on. But the TL;DR; verion is that types that share an underlying type can be converted directly.
x := string("foo")
y = A1(x)
fmt.Println(x, y) // Prints: foo foo
Automatic conversion can also happen when passing arguments to functions which accept arguments of the same underlying type:
func display(x string) {
fmt.Println(x)
}
x := A1("bar")
display(x) // Prints: bar
Although display() takes an argument of type A1, and not string, because they share the same underlying type, conversion happens automatically.
Quotes from The Go Programming Language Specification Version of December 15, 2022