go遗传与多态性

go遗传与多态性,go,polymorphism,Go,Polymorphism,此代码无法正确运行: package main import "fmt" type Human interface { myStereotype() string } type Man struct { } func (m Man) myStereotype() string { return "I'm going fishing." } type Woman struct { } func (m Woman) myStereotype() string { r

此代码无法正确运行:

package main
import "fmt"

type Human interface {
    myStereotype() string
}

type Man struct {
}

func (m Man) myStereotype() string {
    return "I'm going fishing."
}

type Woman struct {
}

func (m Woman) myStereotype() string {
    return "I'm going shopping."
}
func main() {
    var m *Man
    m = new (Man)
    w := new (Woman)

    var hArr []*Human

    hArr = append(hArr, m)
    hArr = append(hArr, w)

    for n, _ := range (hArr) {

        fmt.Println("I'm a human, and my stereotype is: ",
                hArr[n].myStereotype())
    }
}
它存在于:

tmp/sandbox637505301/main.go:29:18: cannot use m (type *Man) as type *Human in append:
*Human is pointer to interface, not interface
tmp/sandbox637505301/main.go:30:18: cannot use w (type *Woman) as type *Human in append:
*Human is pointer to interface, not interface
tmp/sandbox637505301/main.go:36:67: hArr[n].myStereotype undefined (type *Human is pointer to interface, not interface)
但这一条运行正确(var hArr[]*Human被重写为var hArr[]Human):

我不明白为什么。既然m和w都是指针,为什么当我将hArr定义为人类的指针数组时,代码会失败呢


感谢您的解释

您的主要问题是使用了指向接口的指针。我对的回答包含了一些关于差异的细节。可以说,指向接口的指针几乎总是错误的

如果将
*人
存储到
(而不是
*人
)中,它会正常工作,因为接口可以毫无问题地存储指针。事实上,通常,您希望默认在接口中存储指针,因为存储在接口中的值无法访问存储类型的指针方法。接口只是一个保存类型的bucket,不管该类型是结构还是指向结构的指针。另一方面,指向接口的指针不是接口,也不具有与接口相同的隐式实现系统。这与不能将
*func()
变量用作函数非常相似。它是指针,不是函数


TL;DR:不要使用指向接口的指针。它几乎从来没有用过,通常只是反映了对接口是什么的误解。

将接口看作更类似于API定义而不是类型可能会有所帮助。满足接口的东西可能已经是结构或指针,因此不需要使用接口指针。如下列文件所述:

指向接口的指针几乎从来没有用过。事实上,Go运行时在几个版本中被特别更改为不再自动取消引用接口指针(就像它对结构指针所做的那样),以阻止它们的使用。在绝大多数情况下,指向接口的指针反映了对接口应该如何工作的误解


Go没有继承,因此不存在“is a”类型的多态性
package main
import "fmt"

type Human interface {
    myStereotype() string
}

type Man struct {
}

func (m Man) myStereotype() string {
    return "I'm going fishing."
}

type Woman struct {
}

func (m Woman) myStereotype() string {
    return "I'm going shopping."
}
func main() {
    var m *Man
    m = new (Man)
    w := new (Woman)

    var hArr []Human // <== !!!!!! CHANGED HERE !!!!!!

    hArr = append(hArr, m)
    hArr = append(hArr, w)

    for n, _ := range (hArr) {

        fmt.Println("I'm a human, and my stereotype is: ",
                hArr[n].myStereotype())
    }
}
I'm a human, and my stereotype is:  I'm going fishing.
I'm a human, and my stereotype is:  I'm going shopping.