Assignability

June 5, 2023

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 type V is assignable to a variable of type T (“x is assignable to T”) if one of the following conditions applies:

  • V and T are identical.
var x int = 3
var y int = x // Identical types
  • V and T have identical underlying types but are not type parameters and at least one of V or T is not a named type.
var x int = 3
type MyInt int
var y MyInt = x // Identical underlying types
  • V and T are channel types with identical element types, V is a bidirectional channel, and at least one of V or T 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, and x implements T.
var x *os.File
var y io.Reader = x
  • x is the predeclared identifier nil and T 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
const x 1234
var y int = x
var y2 float64 = x

Quotes from The Go Programming Language Specification Version of December 15, 2022


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Comparison operators

I’ll be livestreaming again today! I hope you can join me as I continue where I left off last week, adding some new features to my open-source library, Kivik! Let’s talk about a mundane detail… that actually has some interesting nuances: Comparisons! Comparison operators Comparison operators compare two operands and yield an untyped boolean value. == equal != not equal < less <= less or equal > greater >= greater or equal In any comparison, the first operand must be assignable to the type of the second operand, or vice versa.


Assignability of composite components

Composite literals … The types of the elements and keys must be [assignable(https://go.dev/ref/spec#Assignability)] to the respective field, element, and key types of type T; there is no additional conversion. This shouldn’t be surprising, but let’s examine the implications just the same. type myStr string s := myStr("my string") var x = map[int]string{ 3: "oink", // Valid, untyped numeric constant 3 is assignable to an int. int(4): "quack", // Valid, int(4) is of type int int64(12): "moo", // Invalid, int64(12) is not converted to int 8: s, // Invalid, type myStr is type string 9: string(s), // Valid; explicit conversion to type string } Quotes from The Go Programming Language Specification Version of August 2, 2023


Assignability of type parameters

Let’s finish up our discussion of assignability by looking at how type parameters are special. Assignability … Additionally, if x’s type V or T are type parameters, x is assignable to a variable of type T if one of the following conditions applies: x is the predeclared identifier nil, T is a type parameter, and x is assignable to each type in T’s type set. func foo[T *int | *int32](t T) { t = nil } V is not a named type, T is a type parameter, and x is assignable to each type in T’s type set.

Get daily content like this in your inbox!

Subscribe