0

Need a fresh look because something I do, I get wrong here. I tried to append status to a slice, it wouldn't work

I tried using dereferencing as well

type ServerStatuses []ServerStatus
statuses := new(ServerStatuses)

status := &ServerStatus{
    time:      time,
    available: available,
    url:       url,
}

statuses = append(statuses, *status)

append will not work in such case in spite of statuses is a slice.

Dmitry Dyachkov
  • 1,715
  • 2
  • 19
  • 46

2 Answers2

5

It's nothing to do with the named type. It's because statuses is a *ServerStatuses, which is a pointer to a slice, not a slice. You can only append to slices, not to pointers. Remember that new returns a pointer to the given type. If you replace new(ServerStatuses) with ServerStatuses{}, it works: https://play.golang.org/p/OYdTbLoVifD

Adrian
  • 42,911
  • 6
  • 107
  • 99
  • Thanks, Adrian. Will the dereferencing help? – Dmitry Dyachkov Aug 02 '19 at 14:48
  • If I return a slice from function do I need to return a reference or slices are already passed by pointer? – Dmitry Dyachkov Aug 02 '19 at 14:50
  • 1
    Slices are passed by value like everything else in Go. Pointers are pointers, everything else is not. Whether you need to return a pointer from a function depends entirely on the context, that's not a question that has a universally-applicable answer. – Adrian Aug 02 '19 at 14:57
  • @Adrian If i am not wrong, then `slices` are passed by reffernce unlike other types. See, https://play.golang.org/p/83BHVZgwLN3. – Shudipta Sharma Aug 02 '19 at 15:14
  • Nope - nothing in Go is passed by reference. Slices contain an internal pointer to an array which may be shared among multiple slices of the same array, but the slices themselves are still values. – Adrian Aug 02 '19 at 15:17
  • Sorry for my wrong, and offcourse yes, you are right. `Slices` are passed by value. I have taken a look into https://stackoverflow.com/questions/39993688/are-golang-slices-passed-by-value. – Shudipta Sharma Aug 02 '19 at 15:28
4

In Go, the new built-in function returns a pointer of specified type. So, new(ServerStatuses) gives you a pointer of ServerStatuses, type (*ServerStatuses).

And also you are using an append statement. But append() only appends to a slice. You are trying to append the pointed value of status var of type SeverStatus to the var statuses of type *ServerStatuses. That's why it's not going as you expect. If we simulate the statement you used against the corresponding types of the var:

statuses           =    append(  statuses,         *status       )
*ServerStatuses   <--   append(  *ServerStatuses,  ServerStatus  )

So, you have to declare statuses var as a slice type. For example,

statuses := make(ServerStatuses, 0)

See, an example https://play.golang.org/p/RXETzrxSVqm

Dave C
  • 7,729
  • 4
  • 49
  • 65
Shudipta Sharma
  • 5,178
  • 3
  • 19
  • 33