Now we get to tie a bunch of the past concepts together in a more concrete way, with assignability. Which types of values can be assigned to which types of variables? That’s what this is all about. It’s mostly intuitive, and in fact, I virtually never find myself wondering about these details while coding. But the details do matter. So let’s look at them, with examples.
Assignability
A value
x
of typeV
is assignable to a variable of typeT
(“x is assignable to T”) if one of the following conditions applies:
V
andT
are identical.
var x int = 3
var y int = x // Identical types
V
andT
have identical underlying types but are not type parameters and at least one ofV
orT
is not a named type.
var x int = 3
type MyInt int
var y MyInt = x // Identical underlying types
V
andT
are channel types with identical element types,V
is a bidirectional channel, and at least one ofV
orT
is not a named type.
var x chan int // x's type `V` is `chan int`
var y chan<- int = x // Identical element types, V is bidirectional
T
is an interface type, but not a type parameter, andx
implementsT
.
var x *os.File
var y io.Reader = x
x
is the predeclared identifiernil
andT
is a pointer, function, slice, map, channel, or interface type, but not a type parameter.
var a *int = nil
var b func() error = nil
var c map[string]any = nil
var d chan int = nil
var e io.Reader = nil
x
is an untyped constant representable by a value of typeT
.
const x 1234
var y int = x
var y2 float64 = x
Quotes from The Go Programming Language Specification Version of December 15, 2022