Why does assigning different types work with arrays and slices and not with regular variables?

I created 3 types, for variables (MyType1: int32 ), arrays (MyType2: [2]int32 ) and slices (MyType3: []int ). When I try to assign myType1(7) to variable, it gives error (IncompaibleAssign). That’s expected behavior for me, because constant 7 of type myType1 can’t be assign to variable of type int32. On the other side, assigning different types for arrays and slices somehow works. For example, myType2{20, 40} somehow can be assign to array which type is [2]int32. How is it possible? I expected that i need to convert it like var array [2]int32 = [2]int32(myType2{20, 40}) or change array type to myType2 . Just don’t tell me it’s because of the underlying type. I mean, then nothing will be clear to me anymore, because then why wouldn’t it work for a variable as well?

package main

func main() {

    type myType1 int32
    var variable int32 = myType1(7)

    type myType2 [2]int32
    var array [2]int32 = myType2{20, 40}

    type myType3 []int32
    var slice []int32 = myType3{20, 40}

    _, _, _ = variable, array, slice
1 Like

Hi @Grujic_Filip the response here i think is the following.
You want force to assign a constant to a variable which you think denote the same type. Ok, bot int32 and myType1 denote int32 as their underlying type, but when you calculate a constant the underlying type (which is in this case a built-in) Go gives you myType1 itself, and so returns IncompatibleAssign. Try indeed to print the two types after generating two different constants of int32 and myType1. It’s a specific Go rule Go conversions and assignments

Indeed, if you write something like this, it works:

type myType1 int32
var variable = int32(myType1(5))

In the case of int slices or arrays, they’re treated like the first underlying type, which is int32 pointer. Look this for more informations : Go Type System

I hope this is useful :slightly_smiling_face: enough.

1 Like

Interesting question! I think it’s because of the 2nd condition under the Assignability section of the language specification:

So because myType2’s underlying type is [2]int32 and you’re assigning to [2]int32, it’s OK. If you had 2 different named types whose underlying types are [2]int32, it doesn’t work, though:

type myType2a [2]int32
type myType2b [2]int32
var array myType2b = myType2a{20, 40}
// error: cannot use myType2a{…} (value of type myType2a) as type myType2b in variable declaration

The Go Play Space

1 Like

Thank you for your reply. I think this happens because of “assignment rules”. More specifically, the rule about assigning named and unnamed types with the same underling type. @skillian explained it in more detail.