2016-12-21 2 views
1

Попытка сделать ломтик и проблемы с литералами и указателями. Похоже, что при добавлении на мой фрагмент ему не нравится факт вручения указателя. Например, у меня есть тип пакета, который я сделал вызываемыми компонентами, и имеет тип Component. Смотри ниже.Return Literal vs Pointer

package components 

import() 

type Component struct { 
Name string 
Element string 
Color string 
} 

func (c *Component) SetName(name string) { 
    c.Name = name 
} 

func (c *Component) SetElement(element string) { 
c.Element = element 
} 

func (c *Component) SetColor(color string) { 
    c.Color = color 
} 

func (c *Component) GetName() string { 
    return c.Name 
} 

func (c *Component) GetColor() string { 
    return c.Color 
} 

func (c *Component) GetElement() string { 
    return c.Element 
} 

func NewComponent(name string, color string, element string) *Component { 
    c := &Component{} 
    c.SetName(name) 
    c.SetColor(color) 
    c.SetElement(element) 
    return c 
} 

Теперь я пытаюсь сделать ломтик положить все свои компоненты в творю компоненты Колдовство как снег, песок, Солнечный луч, Спрингуотер и т.д.

//Creating SpringWater Component with Setters 
    SpringWater := components.Component{} 
    SpringWater.SetName("SpringWater") 
    SpringWater.SetColor("Blue") 
    SpringWater.SetElement("Water") 

    //Creating Sand Component using the Constructor 
    Sand := components.NewComponent("Sand", "Red", "Earth") 

ОШИБКА ПРОИСХОДИТ ЗДЕСЬ НА COMPLILE: compSlice: = сделать ([] components.Component, 5) compSlice = добавления (compSlice, родниковой, песок)

ОШИБКА: Невозможно использовать Sa nd как type (* components.Component) как компоненты типа. Компонент в append.

Теперь использование Setters и настройка полей DIRECT Я могу добавить его на срез, но используя метод, он возвращает указатель *, а срез не будет соответствовать. Я просто не понимаю и имею сложную проблему. Имейте в виду, что я новичок в программировании и в основном прихожу от сценариев, поэтому прощайте меня по этому поводу и видели похожие вопросы, но не понимаете в этом контексте.

+2

И комментарий на ваш дизайн. Если вы хотите скрыть свои члены структуры за функциями типа «SetName», вы должны сделать их строчными. Если вы сделаете их UpperCase, тогда они станут общедоступными для использования напрямую. И я сделал бы это так, потому что считаю, что функция скрывается, чтобы быть глупым, хотя вам это нужно для интерфейсов Go, но что угодно. –

+0

ОК. Я еще немного пообщаюсь с ним и дам вам знать, что я придумал, или если я все еще боюсь. Я понятия не имел, что полезные люди ответят мне так скоро! Спасибо, парни – RedBloodMage

ответ

1

Go скрывает разницу между значениями и указателями в нескольких местах, но не везде.

В этой ситуации вам придется разыменования Sand и написать compSlice = append(compSlice, SpringWater, *Sand)

1

component.Component и *component.Component различные типы в Go. Вы хотите, чтобы этот кусочек был compSlice := make([]*component.Component, 5) или append(compSlice, *SpringWater).

Методы, которые вы определили, имеют дело с *component.Component не component.Component.

1

Оба предыдущих ответа верны.

В моем ответе я добавил ваш код к пакету main, и я добавил комментарии в main function, чтобы помочь вам понять, что происходит в вашем коде.

Вот код с комментариями:

package main 

import (
    "fmt" 
) 

type Component struct { 
    Name string 
    Element string 
    Color string 
} 

func (c *Component) SetName(name string) { 
    c.Name = name 
} 

func (c *Component) SetElement(element string) { 
    c.Element = element 
} 

func (c *Component) SetColor(color string) { 
    c.Color = color 
} 

func (c *Component) GetName() string { 
    return c.Name 
} 

func (c *Component) GetColor() string { 
    return c.Color 
} 

func (c *Component) GetElement() string { 
    return c.Element 
} 

func NewComponent(name string, color string, element string) *Component { 
    c := &Component{} 
    c.SetName(name) 
    c.SetColor(color) 
    c.SetElement(element) 
    return c 
} 

func main() { 

    // NewComponent will return a *Component type 
    // So Sand will we a *Component type 
    Sand := NewComponent("Sand", "Red", "Earth") 
    // You can create a slice of []*Component 
    compSlice := make([]*Component, 5) 
    // Then append Sand which is a *Component Slice 
    compSlice = append(compSlice, Sand) 
    // Result: Will be the reference of Sand which is a reference of Component struct 
    // [<nil> <nil> <nil> <nil> <nil> 0xc8200121b0] 
    fmt.Println(compSlice) 
    // Or, you can create a lice of []Component 
    newCompSlice := make([]Component, 5) 
    // Then append the reference of Sand which is *Sand 
    newCompSlice = append(newCompSlice, *Sand) 
    // Result: will be the literal Component struct 
    // [{ } { } { } { } { } {Sand Earth Red}] 
    fmt.Println(newCompSlice) 
} 

Кроме того, вы можете запустить его в: repl.it