Setter方法未设置Golang的结构属性。

huangapple go评论92阅读模式
英文:

Setter method not setting struct property Golang

问题

我需要帮助理解为什么会出现这个错误:

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

> prog.go:56: 无法将MammalImpl字面量(类型为MammalImpl)用作Mammal数组元素的类型:MammalImpl未实现Mammal(SetName方法具有指针接收器)prog.go:57: 无法将MammalImpl字面量(类型为MammalImpl)用作Mammal数组元素的类型:MammalImpl未实现Mammal(SetName方法具有指针接收器)

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

 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") // 这个修改没有任何效果,并且会抛出错误
		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

英文:

I need help with understanding why this error is being thrown:

I am using a pointer because I want it to update the field.

> prog.go:56: cannot use MammalImpl literal (type MammalImpl) as type
> Mammal in array element: MammalImpl does not implement Mammal
> (SetName method has pointer receiver) prog.go:57: cannot use
> MammalImpl literal (type MammalImpl) as type Mammal in array element:
> MammalImpl does not implement Mammal (SetName method has pointer
> receiver)

I am not sure why this is unable to set/override the name property as follows.

 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 code is here http://play.golang.org/p/EyJBY3rH23

答案1

得分: 3

问题在于你有一个带有指针接收器的方法SetName()

func (m *MammalImpl) SetName(s string)

因此,如果你有一个类型为MammalImpl的值,该值的方法集不包含SetName()方法,因此它不实现Mammal接口。

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

因此,当你填充mammals切片时,你必须使用*MammalImpl值进行填充,因为它实现了切片的元素类型(即Mammal)。如果你已经有一个MammalImpl值,你可以很容易地获得一个指向MammalImpl的指针:使用地址&运算符生成指向该值的指针:

mammals := []Mammal{
    &MammalImpl{1, "Carnivorious"},
    &MammalImpl{2, "Ominivorious"},
}

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

英文:

The problem is that you have a method SetName() which has a pointer receiver:

func (m *MammalImpl) SetName(s string)

So if you have a value of type MammalImpl, the method set of that value does not contain the SetName() method therefore it does not implement the Mammal interface.

But the method set of a pointer to MammalImpl (*MammalImpl) will contain the SetName() method therefore it will implement the Mammal interface.

So when you populate the mammals slice, you have to populate it with *MammalImpl values, because that is the one that implements the element type of the slice (which is Mammal). You can easily obtain a pointer to a MammalImpl if you already have a MammalImpl value: use the address & operator to generate a pointer to the value:

mammals := []Mammal{
	&MammalImpl{1, "Carnivorious"},
	&MammalImpl{2, "Ominivorious"},
}

Try your modified program on the Go Playground.

huangapple
  • 本文由 发表于 2015年2月9日 01:49:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/28397240.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定