我需要了解为什么会引发此错误的帮助:

我使用指针,是因为我希望它更新字段。



我不确定为什么无法按以下方式设置/覆盖name属性。

 package main

import (
    "fmt"
)

type Mammal interface {
    GetID() int
    GetName() string
    SetName(s string)
}

type Human interface {
    Mammal

    GetHairColor() string
}

type MammalImpl struct {
    ID   int
    Name string
}

func (m MammalImpl) GetID() int {
    return m.ID
}

func (m MammalImpl) GetName() string {
    return m.Name
}

func (m *MammalImpl) SetName(s string) {
    m.Name = s
}

type HumanImpl struct {
    MammalImpl
    HairColor string
}

func (h HumanImpl) GetHairColor() string {
    return h.HairColor
}

func Names(ms []Mammal) *[]string {
    names := make([]string, len(ms))
    for i, m := range ms {
        m.SetName("Herbivorous") // This modification is not having any effect and throws and error
        names[i] = m.GetName()
    }
    return &names
}

func main() {
    mammals := []Mammal{
        MammalImpl{1, "Carnivorious"},
        MammalImpl{2, "Ominivorious"},
    }

    numberOfMammalNames := Names(mammals)
    fmt.Println(numberOfMammalNames)
}

Go Playground代码在这里http://play.golang.org/p/EyJBY3rH23

最佳答案

问题是您有一个SetName()方法,它具有一个指针接收器:

func (m *MammalImpl) SetName(s string)

因此,如果您具有类型MammalImpl的值,则该值的方法集不包含SetName()方法,因此它不实现Mammal接口(interface)。

但是指向MammalImpl(*MammalImpl)的指针的方法集将包含SetName()方法,因此它将实现Mammal接口(interface)。

因此,当您填充mammals slice 时,必须使用*MammalImpl值填充它,因为那是实现 slice 的元素类型(即Mammal)的值。如果您已经具有MammalImpl值,则可以轻松获得指向MammalImpl的指针:使用address & operator生成指向该值的指针:
mammals := []Mammal{
    &MammalImpl{1, "Carnivorious"},
    &MammalImpl{2, "Ominivorious"},
}

Go Playground上尝试修改后的程序。

10-02 23:20