Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a struct to an array of structs in Go

Tags:

arrays

struct

go

In golang I'm trying to make an array of messages, and the ability to easily add a new "object" to the array.

type Message struct {
    Name string
    Content string
}

var Messages = []Message{
    {
        Name: "Alice",
        Content: "Hello Universe",
    },{
        Name: "Bob",
        Content: "Hello World",
    },
}

func addMessage(m string) {
    var msg = new(Message)
    msg.Name = "Carol"
    msg.Content = m
    Messages = append(Messages, msg)
}

When building I get an error that says:

cannot use msg (type *Message) as type Message in append

Why is append() not working (as I might expect from JavaScript's array.concat()), or is new() not working?

Any other tips on how to improve this code are welcome since I'm obviously new to Go.

like image 329
Luke Avatar asked Jul 19 '16 04:07

Luke


People also ask

Can you put a struct in an array?

Each element of the array can be int, char, float, double, or even a structure. We have seen that a structure allows elements of different data types to be grouped together under a single name. This structure can then be thought of as a new data type in itself. So, an array can comprise elements of this new data type.

How do you use an array of structs in Golang?

In the Go language, you can set a struct of an array. To do so see the below code example. Where type company struct has a slice of type employee struct. Here, you can see the two different structs, and the employee struct is used as an array in the company struct.


2 Answers

Change these 3 lines

var msg = new(Message)
msg.Name = "Carol"
msg.Content = m

to

msg := Message{
    Name:    "Carol",
    Content: m,
}

and everything should work. new creates a pointer to Message. Your slice is not a slice of Message pointers, but a slice of Messages.

like image 54
sberry Avatar answered Oct 28 '22 05:10

sberry


In your code, Messages is a slice of Message type, and you are trying to append a pointer of Message type (*Message) to it.

You can fix your program by doing the following:

func addMessage(m string) {
    var msg = new(Message) // return a pointer to msg (type *msg)
    msg.Name = "Carol"
    msg.Content = m
    Messages = append(Messages, *msg) // use the value pointed by msg
}

Alternatively, you can declare Messages as a slice of *Message:

var Messages = []*Message{
    &Message{ // Now each entry must be an address to a Message struct
        Name: "Alice",
        Content: "Hello Universe",
    },
    &Message{
        Name: "Bob",
        Content: "Hello World",
    },
}

In above case, addMessage wouldn't require any changes. But you'll have to modify Messages access everywhere else.

like image 43
abhink Avatar answered Oct 28 '22 07:10

abhink