Skip to content

Instantly share code, notes, and snippets.

@GregWWalters
Created April 21, 2021 17:31
Show Gist options
  • Save GregWWalters/62d091549f330d648b2aaf12ce6629ff to your computer and use it in GitHub Desktop.
Save GregWWalters/62d091549f330d648b2aaf12ce6629ff to your computer and use it in GitHub Desktop.
References to Slices in Go

In most situations, a reference to a slice in Go is unnecessary. The slice itself contains a pointer to the underlying array, so slices passed as arguments to functions or variables set to slices that are properties of structs can modify the elements of the original slice.

However, if you need to add new elements to the slice, the slice is replaced. By using a reference to the slice, structs and out-of-scope slices can be grown.

For a more complete explanation of why references to slices aren't pointless, check out this Medium article.

package main
import "log"
type container struct {
list []int
}
func (c *container) append(i int) {
list := c.list
list = append(list, i)
}
func (c *container) appendWithPointer(i int) {
list := &c.list
*list = append(*list, i)
}
func (c *container) prepend(i int) {
list := c.list
newList := make([]int, len(list)+1)
newList[0] = i
copy(newList[1:], list)
list = newList
}
func (c *container) prependWithPointer(i int) {
list := &c.list
last := len(*list) - 1
*list = append(*list, (*list)[last])
copy((*list)[1:], (*list)[:last])
(*list)[0] = i
}
func main() {
c1 := &container{list: []int{0}}
c2 := &container{list: []int{0}}
// without pointers
log.Println("c1:", c1.list)
c1.append(1)
log.Println("c1:", c1.list)
c1.prepend(2)
log.Println("c1:", c1.list)
// with pointers
log.Println("c2:", c2.list)
c2.appendWithPointer(1)
log.Println("c2:", c2.list)
c2.prependWithPointer(2)
log.Println("c2:", c2.list)
}
/* Results:
c1: [0]
c1: [0]
c1: [0]
c2: [0]
c2: [0 1]
c2: [2 0 1]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment