Underlying types
May 23, 2023
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
T
has an underlying type: IfT
is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type isT
itself. Otherwise,T
’s underlying type is the underlying type of the type to whichT
refers 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
, andB2
isstring
. The underlying type of[]B1
,B3
, andB4
is[]B1
. The underlying type ofP
isinterface{}
.
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