直接上代码:

首先,我定了三个接口、一个结构和三个方法:

type DeptModeFull interface {
    Name() string
    SetName(name string)
    Relocate(building string, floor uint8)
}

type DeptModeA interface {
    Name() string
    SetName(name string)
}

type DeptModeB interface {
    Relocate(building string, floor uint8)
}

type Dept struct {
    name     string
    building string
    floor    uint8
    Key      string
}

func (self Dept) Name() string {
    return self.name
}

func (self Dept) SetName(name string) {
    self.name = name
}

func (self *Dept) Relocate(building string, floor uint8) {
    self.building = building
    self.floor = floor
}

而后我写了一些测试代码:

dept1 :=
    Dept{
        name:     "MySohu",
        building: "Internet",
        floor:    7}
switch v := interface{}(dept1).(type) {
case DeptModeFull:
    fmt.Printf("The dept1 is a DeptModeFull.\n")
case DeptModeB:
    fmt.Printf("The dept1 is a DeptModeB.\n")
case DeptModeA:
    fmt.Printf("The dept1 is a DeptModeA.\n")
default:
    fmt.Printf("The type of dept1 is %v\n", v)
}
deptPtr1 := &dept1
if _, ok := interface{}(deptPtr1).(DeptModeFull); ok {
    fmt.Printf("The deptPtr1 is a DeptModeFull.\n")
}
if _, ok := interface{}(deptPtr1).(DeptModeA); ok {
    fmt.Printf("The deptPtr1 is a DeptModeA.\n")
}
if _, ok := interface{}(deptPtr1).(DeptModeB); ok {
    fmt.Printf("The deptPtr1 is a DeptModeB.\n")
}

打印出的内容:

The dept1 is a DeptModeA.

The deptPtr1 is a DeptModeFull.

The deptPtr1 is a DeptModeA.

The deptPtr1 is a DeptModeB.

我的问题:

为什么Dept的实例的指针被判定为全部三个接口的实现,而Dept的实例只是DeptModeA接口的实现?

哪位大牛给讲讲?

回答1:

回答2:

========================================================================

另外一个例子


type Reader interface {
    read()
}
type Writer interface {
    write()
}

//定义上述两个接口的实现类
type MyReadWrite struct{}

func (mrw *MyReadWrite) read() {
    fmt.Println("MyReadWrite...read")
}

func (mrw *MyReadWrite) write() {
    fmt.Println("MyReadWrite...write")
}

//定义一个接口,组合了上述两个接口
type ReadWriter interface {
    Reader
    Writer
}

//上述接口等价于:
type ReadWriterV2 interface {
    read()
    write()
}

//ReadWriter和ReadWriterV2两个接口是等效的,因此可以相互赋值
func interfaceTest0104() {
    mrw := MyReadWrite{}
    mrw.read()
    mrw.write()
    //mrw对象实现了read()方法和write()方法,因此可以赋值给ReadWriter和ReadWriterV2
    var rw1 ReadWriter = mrw
    rw1.read()
    rw1.write()

    fmt.Println("------")
    var rw2 ReadWriterV2 = mrw
    rw2.read()
    rw2.write()

    //同时,ReadWriter和ReadWriterV2两个接口对象可以相互赋值
    rw1 = rw2
    rw2 = rw1
}

func main(){
    interfaceTest0104()
}


标红的两行会报错

main\interface.go:43:6: cannot use mrw (type MyReadWrite) as type ReadWriter in assignment:
    MyReadWrite does not implement ReadWriter (read method has pointer receiver)
main\interface.go:48:6: cannot use mrw (type MyReadWrite) as type ReadWriterV2 in assignment:
    MyReadWrite does not implement ReadWriterV2 (read method has pointer receiver)

因为ReadWriter 和ReadWriterV2 的实现都是接受的指针参数,就是*T receiver,而mrw只有T receiver,并没有实现参数为指针的方法(这里的mrw可能没有实现任何方法,mrw.read()能成功是因为上面提到的第三点),所以无法赋值

改成 mrw := &MyReadWrite{} 就不会出错