[types] 별칭 함수를 입력하고 캐스팅하지 않고 사용할 수있는 이유는 무엇입니까?

Go에서 새 유형을 정의하는 경우 예 :

type MyInt int

그런 다음 MyIntint를 기대하는 함수에 를 전달할 수 없으며 그 반대의 경우도 마찬가지입니다.

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
}

이제 첫 번째 예제에서해야하는 것처럼 명시 적 newfunc으로 type 으로 캐스팅 할 필요가 없기 때문에 불평하지 않습니다 MyFunc. 일관성이 없어 보입니다. 그럴만 한 이유가 있다고 확신합니다. 누구든지 나를 깨달을 수 있습니까?

내가 묻는 이유는 주로 이런 방식으로 다소 긴 함수 유형 중 일부를 단축하고 싶지만이 작업을 수행하는 것이 예상되고 수용 가능한지 확인하고 싶습니다. 🙂



답변

이것은 내가 Go가 타입을 어떻게 다루 었는지에 대한 오해입니다. 이것은 스펙의 관련 부분을 읽으면 해결할 수 있습니다.

http://golang.org/ref/spec#Type_identity

내가 몰랐던 것을 관련 구별은의이었다 라는 이름이름이 유형.

명명 된 유형은 int, int64, float, string, bool과 같은 이름을 가진 유형입니다. 또한 ‘type’을 사용하여 만드는 모든 유형은 명명 된 유형입니다.

이름이없는 유형은 [] string, map [string] string, [4] int와 같은 유형입니다. 이름이없고 단순히 구조화 방법에 해당하는 설명입니다.

두 개의 명명 된 유형을 비교하는 경우 이름이 일치해야 상호 교환 할 수 있습니다. 명명 된 유형과 명명되지 않은 유형을 비교하는 경우 기본 표현이 일치 하는 한 계속 진행할 수 있습니다!

예를 들어 다음과 같은 유형이 주어집니다.

type MyInt int
type MyMap map[int]int
type MySlice []int
type MyFunc func(int)

다음은 유효하지 않습니다.

var i int = 2
var i2 MyInt = 4
i = i2 //both named (int and MyInt) and names don't match, so invalid

다음은 괜찮습니다.

is := make([]int)
m := make(map[int]int)
f := func(i int){}

//OK: comparing named and unnamed type, and underlying representation
//is the same:
func doSlice(input MySlice){...}
doSlice(is)

func doMap(input MyMap){...}
doMap(m)

func doFunc(input MyFunc){...}
doFunc(f)

나는 그것을 빨리 몰랐습니다. 그래서 나는 다른 누군가를 위해 종달새 유형을 조금 명확히하기를 바랍니다! 그리고 처음 생각했던 것보다 훨씬 적은 캐스팅을 의미합니다. 🙂


답변

질문과 답변 모두 꽤 깨달았습니다. 그러나 lytnus의 대답에서 명확하지 않은 구별을 제기하고 싶습니다.

  • 명명 된 유형은 다른 이름을 입력 .

  • 의 변수 명명 된 유형 의 변수에 할당 할 이름을 입력 , 반대의 경우도 마찬가지.

  • 다른 Named Type의 변수는 서로 할당 할 수 없습니다.

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
}


답변