116

Go で新しい型を定義すると、次のようになります。

type MyInt int

次に、int を期待する関数にa を渡すことはできませんMyInt。その逆も同様です。

func test(i MyInt) {
    //do something with i
}

func main() {
    anInt := 0
    test(anInt) //doesn't work, int is not of type MyInt
}

罰金。しかし、同じことが関数には当てはまらないのはなぜでしょうか? 例えば:

type MyFunc func(i int)
func (m MyFunc) Run(i int) {
    m(i)
}

func run(f MyFunc, i int) {
    f.Run(i)
}

func main() {
    var newfunc func(int) //explicit declaration
    newfunc = func(i int) {
        fmt.Println(i)
    }
    run(newfunc, 10) //works just fine, even though types seem to differ
}

最初の例で行う必要があるように、newfunctypeに明示的にキャストする必要がなくなるので、今は文句を言っているわけではありません。MyFunc矛盾しているようです。それには十分な理由があると確信しています。誰かが私を啓発できますか?

私が尋ねる理由は主に、かなり長い関数型のいくつかをこのように短縮したいからですが、これを行うことが期待され、受け入れられることを確認したいのです:)

4

2 に答える 2

20

Both the question and answer are pretty enlightening. However, I'd like to bring up a distinction which is not clear in lytnus's answer.

  • Named Type is different from Unnamed Type.

  • Variable of Named Type is assignable to variable of Unnamed Type, vice versa.

  • Variable of different Named Type is not assignable to each other.

http://play.golang.org/p/uaYHEnofT9

import (
    "fmt"
    "reflect"
)

type T1 []string
type T2 []string

func main() {
    foo0 := []string{}
    foo1 := T1{}
    foo2 := T2{}
    fmt.Println(reflect.TypeOf(foo0))
    fmt.Println(reflect.TypeOf(foo1))
    fmt.Println(reflect.TypeOf(foo2))

    // Output:
    // []string
    // main.T1
    // main.T2

    // foo0 can be assigned to foo1, vice versa
    foo1 = foo0
    foo0 = foo1

    // foo2 cannot be assigned to foo1
    // prog.go:28: cannot use foo2 (type T2) as type T1 in assignment
    // foo1 = foo2
}
于 2014-08-16T18:14:27.690 に答える