0

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 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.