Go中的函数调用,赋值和“基础类型”

I'm learning Go (like it so far) but I've run into an interesting problem. The code that fails to compile is:

package main

import "fmt"

type MyInt int

func (i MyInt) Double() MyInt {
    return i + i
}

func AddTwo(i int) int {
    return i + 2
}

func main() {
    var a int = 3
    var x MyInt = a  // Why does this fail?
    fmt.Println(x.Double())
    var y int = AddTwo(x)  // Why does this fail?
    fmt.Println(y)
}

Here's the Go Playground link: MyInt

When I try to run this, I get the following errors:

  prog.go:17: cannot use a (type int) as type MyInt in assignment
  prog.go:19: cannot use x (type MyInt) as type int in argument to AddTwo

However, if I'm reading the spec correctly, this code should compile. First of all, the underlying type of MyInt is int according to this section. In fact, one of the examples given is type T1 string and it says the underlying type of T1 is string. So why can't I assign a to x? Don't they have the same underlying type? Same goes for the function call to AddTwo(). Isn't x has the underlying type int? Why can't I use it as an int argument?

Also, how come Double() compiles at all? In the expression i + i I'm adding two MyInt values. The fact that it compiles suggests that MyInt is an int at least in some sense.

Anyhow, I'm a bit confused. So I thought the point of declarations like type MyInt int was that now you can add methods to primitive types. But if you lose the ability to treat them as int (needing to cast), then what's the point of having this whole 'underlying type' business?

Go has a strict type system. Just because your type is merely an alias for int doesn't mean you can interchange the two freely, you'll still have to do a type conversion. Below is a working version of your main, here's the code on play ground; https://play.golang.org/p/kdVY145lrJ

func main() {
    var a int = 3
    var x MyInt = MyInt(a)  // Why does this fail?
    fmt.Println(x.Double())
    var y int = AddTwo(int(x))  // Why does this fail?
    fmt.Println(y)
}