douwen0612 2019-09-25 07:03
浏览 133

关于接口分配

Why doesn't Go think it's type mismatch error when a struct pointer be assigned to an interface?

package main

import "fmt"

type ABC interface {
    a() string
    b() int
}

type XYZ struct {
    aa string
    bb int
}

func (xyz XYZ) a() string {
    return "XYZ"
}

func (xyz XYZ) b() int {
    return 123
}

func main() {
    var xyz *XYZ
    var abc ABC = xyz // type of abc is *main.XYZ,I think that Golang can find this error here, but why not?

    fmt.Printf("%T
", abc)

    a, ret := abc.(*XYZ)
    fmt.Println(a, ret) // type of a is *main.XYZ

    fmt.Println(a.a()) // will occur a error, because the type of a(*main.XYZ) not implements the interface ABC
}

I want know why Go doesn't think this is an error at "var abc ABC = xyz"

  • 写回答

2条回答 默认 最新

  • dongyuli4538 2019-09-25 07:07
    关注

    will occur a error, because the type of a(*main.XYZ) not implements the interface ABC

    Wrong. *main.XYZ implements ABC (else abc = xyz would fail at compile-time, try to rename the method b to c for example), but the variable a holds a nil pointer (of type *XYZ). And since the XYZ.a() method has value receiver, to call that, a pointer value of type *XYZ would have to be dereferenced. But a nil pointer points to nothing, it cannot be dereferenced, an attempt to do so results in a runtime panic, just as you experienced.

    If you would initialize xyz in the beginning with a non-nil pointer, it would work:

    var xyz *XYZ = new(XYZ)
    

    Try it on the Go Playground.

    Also note that if XYZ.a() and XYZ.b() would have pointer receivers, then it would also work if xyz is nil:

    func (xyz *XYZ) a() string {
        return "XYZ"
    }
    
    func (xyz *XYZ) b() int {
        return 123
    }
    
    func main() {
        var xyz *XYZ
        // ...
    

    Try it on the Go Playground. The reason for this is because if the receivers are pointers, the nil pointer does not have to be dereferenced in order to call methods with pointer receivers, so no runtime panic occurs. Of course if in the methods you would refer to the XZY.aa or XYZ.bb fields, that would be a runtime panic, but your current method implementations does not do so, so it works.

    评论

报告相同问题?

悬赏问题

  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了