Golang: Slice

By Xah Lee. Date: . Last updated: .

Slice is like array but length can be changed.

Golang slice is essentially a reference to a segment of array. [see Golang: Array]

Syntax of Slice Type

[]type
Syntax for slice type, with each slot of type type.
Example: var s []string. [see Golang: Basic Datatypes]
package main

import "fmt"

func main() {

	// declare var of type slice
	var ss []int

	// print the type
	fmt.Printf("%T", ss) // []int

}

Literal Expression of Slice

[]type{v1, v2 }
Create a slice with values. Example: var ss = []int{9, 2, 6}
package main

import "fmt"

func main() {

	// slice
	var ss = []int{9, 2, 6}

	fmt.Printf("%v\n", ss) // [9 2 6]
	fmt.Printf("%T\n", ss) // []int

}

Print Slice

fmt.Printf("%v\n", slice)
Print slice in human readable form . Example: [3 4 5]
fmt.Printf("%#v\n", slice)
Print slice in golang syntax. Example: []int{3, 4, 5}
package main

import "fmt"

func main() {

	var sl = []int{3, 4, 5}

	// print it normally
	fmt.Printf("%v\n", sl) // [3 4 5]

	// print in golang syntax
	fmt.Printf("%#v\n", sl) // []int{3, 4, 5}

}

Print Slice Line by Line

To print each member on a line, you have to write a loop.

package main

import "fmt"

func printSlice(sliceX []string) error {
	for k, v := range sliceX {
		fmt.Printf("%v %v\n", k, v)
	}
	return nil
}

// --------------------------------------------------
// test

func main() {

	var fileList = []string{
		"basics.html",
		"tag_matching.html",
		"selector_syntax.html",
		"units.html",
		"colors.html",
		"color_names.html",
		"color_opacity.html",
		"gradient.html",
		"gradient_radial.html"}

	printSlice(fileList)
}

/* 
prints

0 basics.html
1 tag_matching.html
2 selector_syntax.html
3 units.html
4 colors.html
5 color_names.html
6 color_opacity.html
7 gradient.html
8 gradient_radial.html

*/

[see Golang: loop]

Create slice with “make”

You can create a slice with make. It lets you specify how many items to begin with, and capacity for growth.

make([]type, count)
Create a slice of count number of slots of type type.
make([]type, count, capacity)
With capacity of capacity number of slots. capacity defaults to the value of count.
Example: make([]int, 10, 1000)
Note: capacity is not necessary, because golang automatically grow the slice capacity when you append() beyond the capacity. However, capacity is there for efficiency reasons, because creating a new array with lots items is relatively slow. Best to always create a slice with expected growth.
package main

import "fmt"

func main() {

	// 3 slots of int
	var s = make([]int, 3)
	fmt.Println(s) // [0 0 0]

	// 3 slots of int, capacity of 9
	var s2 = make([]int, 3, 9)
	fmt.Println(s2) // [0 0 0]
}

Length

len(s)
Return the length of slice s.

Capacity

cap(s)
Return the capacity.

Slice of Slice

s[a:b]
Return a slice of s from index a to b. The a is included, The b is excluded. The result shares the same data with original. If you modify it, the original will also be modified.
s[:n]
Same as s[0:n]
s[n:]
Same as s[n:len(s)]
package main

import "fmt"

func main() {
	var s = []int{0, 1, 2, 3}

	// take a slice of values
	var x = s[1:3]

	fmt.Println(x) // [1 2]
}

Here's a example where modifying the slice also modifies the original.

package main

import "fmt"

func main() {
	var s = []int{0, 1, 2, 3}

	// take a slice
	var x = s[1:3]

	// modify it
	x[0] = 99

	// original also changed
	fmt.Printf("%v\n", s)
	// [0 99 2 3]

}

Append to Slice

var new_slice = append(slice_x, new_item1, new_item2 etc)
Append new items to a slice.
var new_slice = append(slice_x, slice_y ...)
The dot dot dot turns a slice or string into items as function arguments.
var new_slice = append(slice_x, string ...)
Turn string into a byte slice and append them to slice.

Warning: append creates a new slice only when result length is greater than original slice slice_x's capacity.

Normally, append will always result a slice with capacity greater the original slice , therefore the original slice is not modified. However, if the original slice is a slice of the slice w, and append result is less than capacity of w, then w is modified.

package main

import "fmt"

func main() {

	var ss = []int{3, 5}
	var s2 = append(ss, 8, 9)

	fmt.Println(s2) // [3 5 8 9]

	// original not changed
	fmt.Println(ss) // [3 5]

}

Here's a example of appending a slice.

package main

import "fmt"

func main() {

	var s1 = []int{3, 5}
	var s2 = []int{6, 7}
	var s3 = append(s1, s2...)

	fmt.Println(s3) // [3 5 6 7]

}

Append does not create a new a slice when the result is within original capacity.

Example:

package main

import "fmt"

func main() {

	var x1 = []int{0, 1, 2, 3, 4, 5}
	var x2 = x1[:3] // [0 1 2]

	var x3 = append(x2, 22)

	fmt.Println(x3) // [0 1 2 22]

	// x1 is changed
	fmt.Println(x1) // [0 1 2 22 4 5]

	// --------------------------------------------------
	// if the append added more items than the capacity of x1, then x1 will not be changed
	// now we do the above again to see

	var y1 = []int{0, 1, 2, 3, 4, 5}
	var y2 = y1[:3] // [0 1 2]

	var y3 = append(y2, 21, 22, 23, 24, 25)

	fmt.Println(y3) // [0 1 2 21 22 23 24 25]

	// y1 is not changed
	fmt.Println(y1) // [0 1 2 3 4 5]

}

Cut Slice (Delete Elements)

Use append to delete elements, like this:

s = append(s[:i], s[j:]...)
Delete from index i to j.
package main

import "fmt"

func main() {

	var x = []byte("0123456")

	x = append(x[:3], x[5:]...)

	fmt.Printf("%s\n", x)
	// 1236

}

Copy Slice

copy(dst, src)
Copy elements of slice from src to dst. The number of elements copied is the smaller of lengths of argument, whichever is shorter. It wipes the values in the dst slice starting at index 0. Return the number of items copied.
Arguments must be slice of the same type.
In the case of byte slice, the src can be a string too.
package main

import "fmt"

func main() {
	var x = []int{0, 1, 2, 3, 4, 5}
	var y = []int{99, 999}
	copy(y, x)
	fmt.Println(y) // [0 1]
}

Example of copying shorter to longer:

package main

import "fmt"

func main() {
	var x = []int{99, 999}
	var y = []int{0, 1, 2, 3, 4, 5}
	copy(y, x)
	fmt.Println(y) // [99 999 2 3 4 5]
}

Clear Slice

To clear slice, set it to nil or set it to a slice of 0 length.

mySlice = nil

or

mySlice = mySlice[0:0]

The recommended way is to set to nil.

Nested Slice

Slices can be nested. Just declare that the slots are also type slice.

var x [][]int
Declare a nested slice of int type.
package main

import "fmt"

func main() {
	var x [][]int
	fmt.Println(x) // []
}

Nested Slice with Values

var y = [][]int{{3, 4}, {7}, {1, 2}}
Declare nested slice, with initial values.
package main

import "fmt"

func main() {
	// y is slice of slice of int
	var y = [][]int{{3, 4}, {7, 8, 9}, {1, 2}}
	fmt.Println(y) // [[3 4] [7 8 9] [1 2]]
}

Create Nested Slice with make

var ns = make([][]string, 2)
Create a nested slice.
package main

import "fmt"

func main() {

	// nested slice. 2 items. each item is a slice of string
	var ns = make([][]string, 2)

	// fill the slots
	ns[0] = []string{"a", "b"}
	ns[1] = []string{"x", "y", "z"}

	fmt.Println(ns) // [[a b] [x y z]]
}

Getting and setting values.

package main

import "fmt"

func main() {

	var ss = make([][]int, 2)

	ss[0] = []int{1, 2}
	ss[1] = []int{3, 4}

	ss[1][1] = 5

	fmt.Println(ss) // [[1 2] [3 5]]
}

Slice of Strings to String

strings.Join(slice, seperator)
Join a Slice of Strings to one big string.
package main

import "fmt"
import "strings"

// join slice of strings to one big string

func main() {
	var sls = []string{"abc", "xyz"}
	var result = strings.Join(sls, ",")
	fmt.Printf("%v\n", result)
	// abc,xyz
}

Loop Thru Slice

for i, v := range slice {}
Loop thru slice, where i is current index and v the value. If a variable is not used, name it _ to stop compiler from complaining. Example: for _, v := range slice {}
The _ is called “blank identifier”.
package main

import "fmt"

func main() {
	var s = []int{9, 2, 8, 61}
	for i, x := range s {
		fmt.Println(i, x)
	}
}

// 0 9
// 1 2
// 2 8
// 3 61

Reference

The Go Programming Language Specification - The Go Programming Language#Slice_types

The Go Programming Language Specification - The Go Programming Language#Appending_and_copying_slices

If you have a question, put $5 at patreon and message me.

Golang

Examples

Reference