duanao2688 2013-10-12 13:07
浏览 23
已采纳

为什么可以键入别名函数并在不进行强制转换的情况下使用它们?

In Go, if you define a new type e.g.:

type MyInt int

You can't then pass a MyInt to a function expecting an int, or vice versa:

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

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

Fine. But why is it then that the same does not apply to functions? e.g.:

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
}

Now, I'm not complaining because it saves me having to explicitly cast newfunc to type MyFunc, as I would have to do in the first example; it just seems inconsistent. I'm sure there is a good reason for it; can anyone enlighten me?

The reason I ask is mainly because I would like to shorten some of my rather long function types in this way, but I want to make sure it's expected and acceptable to do this :)

  • 写回答

2条回答 默认 最新

  • duanhuang2150 2013-10-12 13:51
    关注

    Turns out, this is a misunderstanding that I had about how Go dealt with types, which can be resolved by reading the relevant part of the spec:

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

    The relevant distinction that I was unaware of was that of named and unnamed types.

    Named types are types with a name, such as int, int64, float, string, bool. In addition, any type you create using 'type' is a named type.

    Unnamed types are those such as []string, map[string]string, [4]int. They have no name, simply a description corresponding to how they are to be structured.

    If you compare two named types, the names must match in order for them to be interchangeable. If you compare a named and an unnamed type, then as long as the underlying representation matches, you're good to go!

    e.g. given the following types:

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

    the following is invalid:

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

    the following is fine:

    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 :)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 如何绘制动力学系统的相图