Trying to make a slice and having problems with literals and pointers. It looks like when appending onto my slice it does not like the fact of being handed a pointer. For instance I have a package type I made called components and holds type Component. See below.
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
}
Now I am attempting to make a slice to put all my components into I am making spellcasting components like Snow,Sand,Sunbeam,Springwater etc.
//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")
ERROR HAPPENS HERE ON COMPLILE: compSlice := make([]components.Component, 5) compSlice = append(compSlice, SpringWater, Sand)
ERROR: Cannot use Sand as type (*components.Component) as type components.Component in append.
Now using the Setters and Setting the Fields DIRECT I can add it to a slice however using the method it returns a *pointer and the Slice will not comply. I am just not understanding and having a difficult issue. Keep in mind I am new to programming and basically come from scripting so forgive me on this and have seen similar questions but do not understand in this context.
Go hides the difference between values and pointers in several places, but not everywhere.
In this situation you will have to dereference Sand
and write compSlice = append(compSlice, SpringWater, *Sand)
component.Component
and *component.Component
are different types in Go. You're gonna want that slice to be compSlice := make([]*component.Component, 5)
or append(compSlice, *SpringWater)
.
The methods you defined all deal with *component.Component
not component.Component
.
Both previous answers are correct.
In my answer, i've added your code to the main
package and i've added some comments in the main function
to help you understanding what is going in your code.
Here is the code with comments:
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)
}
Also, you can run it in: repl.it