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
xcan be converted to typeTin any of these cases:
xis assignable toT.- ignoring struct tags (see below),
x’s type andTare not type parameters but have identical underlying types.- ignoring struct tags (see below),
x’s type andTare 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)