Yesterday we looked at conversions of constants. Let’s now consider the more common conversion scenarios of variables and other non-constant expressions.
Conversions
…
A non-constant value
x
can be converted to typeT
in any of these cases:
x
is assignable toT
.- ignoring struct tags (see below),
x
’s type andT
are not type parameters but have identical underlying types.- ignoring struct tags (see below),
x
’s type andT
are pointer types that are not named types, and their pointer base types are not type parameters but have identical underlying types.
Let’s look at these last two specifically with examples. Let’s repeat the example from Tuesday:
type User struct {
Username string `json:"username"`
Password string `json:"password"`
}
type UserDisplay struct {
Username string `json:"username"`
Password string `json:"-"`
}
b := User{Username: "bob", Password: "abracadabra"}
bd := UserDisplay(b) // Valid; identical underlying types (ignoring struct tags)
a := &User{Username: "alice", Password: "open sesame"}
ad := (*UserDisplay)(a) // Valid; pointer types are not named
type UserPointer *User
type UserDisplayPointer *UserDisplay
c := UserPointer(&User{Username: "charlie", Password: "hocus pocus"})
cd := (UserDisplayPointer)(c) // cannot convert c (variable of type UserPointer) to type UserDisplayPointer
If you really want to do this latter conversion, you have to take some extra steps, and use this monstrosity:
cd2 := UserDisplayPointer((*UserDisplay)((*User)(c)))
Tomorrow we’ll finish up with conversions of non-generic types, before venturing into that fun area!
Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)