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

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

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方法具有指针接收器)

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

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type Mammal interface {
  6. GetID() int
  7. GetName() string
  8. SetName(s string)
  9. }
  10. type Human interface {
  11. Mammal
  12. GetHairColor() string
  13. }
  14. type MammalImpl struct {
  15. ID int
  16. Name string
  17. }
  18. func (m MammalImpl) GetID() int {
  19. return m.ID
  20. }
  21. func (m MammalImpl) GetName() string {
  22. return m.Name
  23. }
  24. func (m *MammalImpl) SetName(s string) {
  25. m.Name = s
  26. }
  27. type HumanImpl struct {
  28. MammalImpl
  29. HairColor string
  30. }
  31. func (h HumanImpl) GetHairColor() string {
  32. return h.HairColor
  33. }
  34. func Names(ms []Mammal) *[]string {
  35. names := make([]string, len(ms))
  36. for i, m := range ms {
  37. m.SetName("Herbivorous") // 这个修改没有任何效果,并且会抛出错误
  38. names[i] = m.GetName()
  39. }
  40. return &names
  41. }
  42. func main() {
  43. mammals := []Mammal{
  44. MammalImpl{1, "Carnivorious"},
  45. MammalImpl{2, "Ominivorious"},
  46. }
  47. numberOfMammalNames := Names(mammals)
  48. fmt.Println(numberOfMammalNames)
  49. }

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.

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type Mammal interface {
  6. GetID() int
  7. GetName() string
  8. SetName(s string)
  9. }
  10. type Human interface {
  11. Mammal
  12. GetHairColor() string
  13. }
  14. type MammalImpl struct {
  15. ID int
  16. Name string
  17. }
  18. func (m MammalImpl) GetID() int {
  19. return m.ID
  20. }
  21. func (m MammalImpl) GetName() string {
  22. return m.Name
  23. }
  24. func (m *MammalImpl) SetName(s string) {
  25. m.Name = s
  26. }
  27. type HumanImpl struct {
  28. MammalImpl
  29. HairColor string
  30. }
  31. func (h HumanImpl) GetHairColor() string {
  32. return h.HairColor
  33. }
  34. func Names(ms []Mammal) *[]string {
  35. names := make([]string, len(ms))
  36. for i, m := range ms {
  37. m.SetName("Herbivorous") // This modification is not having any effect and throws and error
  38. names[i] = m.GetName()
  39. }
  40. return &names
  41. }
  42. func main() {
  43. mammals := []Mammal{
  44. MammalImpl{1, "Carnivorious"},
  45. MammalImpl{2, "Ominivorious"},
  46. }
  47. numberOfMammalNames := Names(mammals)
  48. fmt.Println(numberOfMammalNames)
  49. }

Go Playground code is here http://play.golang.org/p/EyJBY3rH23

答案1

得分: 3

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

  1. func (m *MammalImpl) SetName(s string)

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

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

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

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

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

英文:

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

  1. 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:

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

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:

确定