2015-02-08 4 views
0

мне нужна помощь с пониманием, почему эта ошибка бросают:сеттер метод не устанавливая STRUCT свойства Golang

Я использую указатель, потому что я хочу, чтобы обновить поле.

prog.go: 56: не может использовать MammalImpl буквального (тип MammalImpl) в качестве типа Млекопитающее в элемент массива: MammalImpl не реализует Млекопитающее (метод SetName имеет указатель приемник) prog.go: 57: не может использовать MammalImpl буквальный (тип MammalImpl) как тип Матт в элементе массива: MammalImpl не реализует Млекопитающее (метод 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") // 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 площадка код здесь http://play.golang.org/p/EyJBY3rH23

ответ

3

Проблема заключается в том, что у вас есть метод SetName() который имеет указатель приемника:

func (m *MammalImpl) SetName(s string) 

Так что если у вас есть значение типа MammalImpl, то метод этого значения не содержит метода SetName(), поэтому он не реализует интерфейс Mammal.

Но метод набора указателя MammalImpl (*MammalImpl) будет содержать метод SetName() поэтому он будет реализовывать интерфейс Mammal.

Итак, когда вы заселить кусочек mammals, вы должны заполнить его *MammalImpl ценности, потому что это один, который реализует тип элемента среза (которая Mammal). Вы можете легко получить указатель на MammalImpl, если у вас уже есть значение MammalImpl: использовать address & operator генерировать указатель на значение:

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

Попробуйте измененную программу на Go Playground.

+0

Я должен вам пиво .. спасибо за миллион –

Смежные вопросы