Programing

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

lottogame 2020. 9. 24. 08:12
반응형

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


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

type MyInt int

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

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)

I'm a bit gutted I didn't know that sooner, so I hope that clarifies the type lark a little for someone else! And means much less casting than I at first thought :)


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
}

참고URL : https://stackoverflow.com/questions/19334542/why-can-i-type-alias-functions-and-use-them-without-casting

반응형