Today we’ll finish the list of non-constant conversion rules that don’t relate to type parameters.
Conversions
…
x
’s type andT
are both integer or floating point types.x
’s type andT
are both complex types.x
is an integer or a slice of bytes or runes andT
is a string type.x
is a string andT
is a slice of bytes or runes.x
is a slice,T
is an array [Go 1.20] or a pointer to an array [Go 1.17], and the slice and array types have identical element types.
The last one is the only one that feels to me like it needs more than a superficial explanation. So let’s talk about that, with some examples of related concepts.
var s = []int{1, 2, 3, 4, 5}
a := [5]int(s) // Valid
b := [3]int(s) // Valid, b contains the first 3 elements of a
c := [10]int(s) // panic: runtime error: cannot convert slice with length 5 to array or pointer to array with length 10
d := [5]int64(s) // cannot convert s (variable of type []int) to type [5]int64
// And you can convert directly to a pointer of a slice
p := (*[5]int)(s) // Valid
// Print out some results for comparison:
fmt.Println(s, a, p) // [1 2 3 4 5] [1 2 3 4 5] &[1 2 3 4 5]
But notice, when using a pointer to an array, as one might expect, we have multiple variables accessing the same underlying memory. This means that if we change an element of s
, the corresponding element pointed to by p
will also change. But not in a
or b
, as these are copies of the individual elements:
s[2] = 99
fmt.Println(s, a, p) // [1 2 99 4 5] [1 2 3 4 5] &[1 2 99 4 5]
Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)