Contents
Outline
In this blog post, I will introduce what the Slice
is and how to use the Slice in Golang. You can see the full source code of this blog post on the link below.
Slice
Slice is the dynamic array type(the pointer to the array) that Golang providers.
- Static: Determined at compile time.
- Dynamic: Determined at runtime.
Next is how to define the array in Golang.
var v [10]int
You can define Slice without setting the size of the array like the below.
var v []int
To check this, create the main.go
file and modify it like the below.
package main
import "fmt"
func main() {
var a [2]string
var b []string
fmt.Println(a)
fmt.Println(b)
}
When you execute the code, you can see the following result.
# go run main.go
[ ]
[]
Array and Slice
Slice is the pointer type to the array. To check this, modify the main.go
file like the below.
package main
import "fmt"
func changeArr(arr2 [5]int) {
arr2[0] = 100
}
func changeSlice(slice2 []int) {
slice2[0] = 100
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
slice := []int{1, 2, 3, 4, 5}
changeArr(arr)
changeSlice(slice)
fmt.Println(arr)
fmt.Println(slice)
}
When the code is executed, the following reult is shown.
# go run main.go
[1 2 3 4 5]
[100 2 3 4 5]
Array is not a pointer type, so when the changeArr
is called, the new instance called arr2
is created, and then arr
is copied to it. So, when arr2
is changed in the changeArr
fucntion, the arr
is not chagned.
However, Slice is a pointer type. So, when the changeSlice
function is called, slice2
gets slice
memory address instead of creating a new instance. So, when slice2
is changed in the changeSlice
function, the slice
is also changed.
len and cap
Slice has len
and cap
data unlike Array(Array has only len
). The len
of Slice is the number of elements in the Slice, and the cap
is the number of elements in the Slice that can be stored without allocating more memory.
To check this, modify the main.go
file like the below.
package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3, 4, 5}
slice2 := make([]int, 2, 10)
fmt.Printf("slice1(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
}
When the code is executed, the following result is shown.
# go run main.go
slice1(0xc0000b2000): len=5 cap=5 [1 2 3 4 5]
slice2(0xc0000b4000): len=2 cap=10 [0 0]
make function
You can create the Slice with the make
function that Golang provides.
slice1 := make([]int, 10)
fmt.Println(slice1)
When you define the Slice like above with the make function, the 10 size Slice is created.
slice2 := make([]int, 2, 10)
fmt.Println(slice2)
Also, you can create the Slice with the make
function with the len
and cap
parameters. When you define the Slice like the above, the 2 len
and 10 cap
size Slice is created.
To check this, modify the main.go
file like the below.
package main
import "fmt"
func main() {
slice1 := make([]int, 10)
fmt.Println(slice1)
slice2 := make([]int, 2, 10)
fmt.Println(slice2)
}
When you execute the code, you can see the following result.
# go run main.go
[0 0 0 0 0 0 0 0 0 0]
[0 0]
Slicing
Creating Slice by cutting part of an array is called Slicing
.
- Array => Slicing => Slice
In Golang, you can use slicing like the below.
Array[startIndex:endIndex]
The slicing above returns the value from startIndex to just before
endIndex(endIndex -1). At this time, the returned Slice cap
is the length from startIndex to the end of Array.
To check this, modify the main.go
file like the below.
package main
import "fmt"
func main() {
array := [5]int{1, 2, 3, 4, 5}
slice := array[1:2]
fmt.Printf("array: len=%d %v\n", len(array), array)
fmt.Printf("slice: len=%d cap=%d %v\n", len(slice), cap(slice), slice)
}
When you execute the code above, you can see the following result.
# go run main.go
array: len=5 [1 2 3 4 5]
slice: len=1 cap=4 [2]
You can also slice the Slice to create a new Slice. Also, you can slice from the first by setting 0 to startIndex
, and you can omit 0
.
slice = []int{1, 2, 3, 4, 5}
slice1 := slice[0:3]
slice2 := slice[:3]
You can slice to the end, and you can omit the last index like the below.
slice = []int{1, 2, 3, 4, 5}
slice1 = slice[2:len(slice)]
slice2 = slice[2:]
Lastly, you can slice all, and this is normally used for converting Array to Slice.
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[:]
Slicing doesn’t create a new variable, just makes a pointer, so you can use it like the below.
array1 := [100]int{1: 1, 2: 2, 99: 100}
slice1 = array1[1:10]
slice2 = slice1[2:99]
fmt.Println(slice1)
fmt.Println(slice2)
As you see, the slice1
has the memory address of array
, so it is possible to create slice2
by taking the values from slice1
to the 99th.
Slicing with cap size
When you slice Array, the returned Slice has the cap
from startIndex to the end of Array. However, when you slice Array with maxIndex
like the below, you can control the cap size.
slice[startIndex:endIndex:maxIndex]
slice1 = []int{1, 2, 3, 4, 5}
slice2 = slice1[1:3:4]
fmt.Printf("slice1: len=%d cap=%d %v\n", len(slice1), cap(slice1), slice1)
fmt.Printf("slice2: len=%d cap=%d %v\n", len(slice2), cap(slice2), sl
append function
When you want to add an element to the end of the Slice, you can use the append
function. When you use the append
function, a new Slice is returned.
var slice1 = []int{1, 2, 3}
slice2 := append(slice1, 4)
At this time, the new Slice has the same memory address as the old Slice, or not.
When you use the append
function to add an element and the target Slice has enough space to store the element, the new Slice uses the old Slice memory address. However, when the target Slice doesn’t have enough space, the append
function copies the old Slice to the new memory address and adds the element to it.
To check this, modify the main.go
file like the below.
package main
import "fmt"
func main() {
slice1 := make([]int, 3)
slice2 := append(slice1, 4)
fmt.Println("[New splice]")
fmt.Printf("slice(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
fmt.Println("slice1 changed ========================================================")
slice1[0] = 100
fmt.Printf("slice(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
fmt.Println("slice2 changed ========================================================")
slice2[0] = 200
fmt.Printf("slice(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
slice1 = make([]int, 1, 3)
slice2 = append(slice1, 4)
fmt.Println("[Same slice]")
fmt.Printf("slice(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
fmt.Println("slice1 changed ========================================================")
slice1[0] = 100
fmt.Printf("slice(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
fmt.Println("slice2 changed ========================================================")
slice2[0] = 200
fmt.Printf("slice(%p): len=%d cap=%d %v\n", slice1, len(slice1), cap(slice1), slice1)
fmt.Printf("slice2(%p): len=%d cap=%d %v\n", slice2, len(slice2), cap(slice2), slice2)
}
When the code is executed, you can see the following result.
# go run main.go
[New splice]
slice(0xc00012a000): len=3 cap=3 [0 0 0]
slice2(0xc00012c000): len=4 cap=6 [0 0 0 4]
slice1 changed ========================================================
slice(0xc00012a000): len=3 cap=3 [100 0 0]
slice2(0xc00012c000): len=4 cap=6 [0 0 0 4]
slice2 changed ========================================================
slice(0xc00012a000): len=3 cap=3 [100 0 0]
slice2(0xc00012c000): len=4 cap=6 [200 0 0 4]
[Same slice]
slice(0xc00012a018): len=1 cap=3 [0]
slice2(0xc00012a018): len=2 cap=3 [0 4]
slice1 changed ========================================================
slice(0xc00012a018): len=1 cap=3 [100]
slice2(0xc00012a018): len=2 cap=3 [100 4]
slice2 changed ========================================================
slice(0xc00012a018): len=1 cap=3 [200]
slice2(0xc00012a018): len=2 cap=3 [200 4]
When the Slice has enough cap
size to store the elements, you can see that the new Slice has the same memory address as the old Slice. Therefore, when you use the append
function, you should care about that the old Slice and new slice can be changed at the same time.
Copy Slice
You can use the slicing to copy the Slice.
slice1 = []int{1, 2, 3, 4, 5}
slice2 = slice1[:]
slice2[1] = 100
fmt.Println(slice1)
fmt.Println(slice2)
However, the slicing just creates a new Slice pointer instead of creating a new Slice, so when you modify the slice2
value like above, the slice
value is also changed.
To solve this issue, you can make a new slice2
that has the same size of the slice
, and loop it to copy the elements.
slice1 = []int{1, 2, 3, 4, 5}
slice2 = make([]int, len(slice1))
for i, v := range slice1 {
slice2[i] = v
}
slice2[1] = 100
fmt.Println(slice1)
fmt.Println(slice2)
Also, you can use the append
function to create a new slice, and add all elements to it.
slice1 = []int{1, 2, 3, 4, 5}
slice2 = append([]int{}, slice1...)
slice2[1] = 100
fmt.Println(slice1)
fmt.Println(slice2)
Lastly, you can use the make
function to create a slice with the same size of the slice1
, and use copy
function to copy the elements.
slice1 = []int{1, 2, 3, 4, 5}
slice2 = make([]int, len(slice1))
copy(slice2, slice1)
slice2[1] = 100
fmt.Println(slice1)
fmt.Println(slice2)
In Golang, you can use the copy
function like the below.
copy(dst, src)
Delete
You can delete a specific element in the Slice like the below.
slice := []int{1, 2, 3, 4, 5, 6}
deleteIdx := 2
fmt.Println(slice)
for i := deleteIdx + 1; i < len(slice); i++ {
slice[i-1] = slice[i]
}
slice = slice[:len(slice)-1]
fmt.Println(slice)
Also, you can use the append
function to delete the element.
slice = []int{1, 2, 3, 4, 5, 6}
deleteIdx = 2
fmt.Println(slice)
slice = append(slice[:deleteIdx], slice[deleteIdx+1:]...)
fmt.Println(slice)
Lastly, you can use the copy
function to delete the element.
slice = []int{1, 2, 3, 4, 5, 6}
deleteIdx = 2
fmt.Println(slice)
copy(slice[deleteIdx:], slice[deleteIdx+1:])
slice = slice[:len(slice)-1]
fmt.Println(slice)
Insert element
In Golang, you can use the for
loop to insert an element to the Slice like the below.
slice := []int{1, 2, 3, 4, 5, 6}
insertIdx := 2
fmt.Println(slice)
slice = append(slice, 0)
for i := len(slice) - 2; i >= insertIdx; i-- {
slice[i+1] = slice[i]
}
slice[insertIdx] = 100
fmt.Println(slice)
Also, you can use the append
function to insert the element.
slice = []int{1, 2, 3, 4, 5, 6}
insertIdx = 2
fmt.Println(slice)
slice = append(slice[:insertIdx], append([]int{100}, slice[insertIdx:]...)...)
fmt.Println(slice)
Lastly, you can use the copy
function to insert the element.
slice = []int{1, 2, 3, 4, 5, 6}
insertIdx = 2
fmt.Println(slice)
slice = append(slice, 0)
copy(slice[insertIdx+1:], slice[insertIdx:])
slice[insertIdx] = 100
fmt.Println(slice)
Slice sorting
You can sort the Slice by the sort
package provided by the Golang.
package main
import (
"fmt"
"sort"
)
func main() {
slice := []int{6, 3, 1, 5, 4, 2}
fmt.Println(slice)
sort.Ints(slice)
fmt.Println(slice)
}
Also, you can sort the structure Slice with the sort
package like the below.
package main
import (
"fmt"
"sort"
)
type Student struct {
Name string
Age int
}
type Students []Student
func (s Students) Len() int { return len(s) }
func (s Students) Less(i, j int) bool { return s[i].Age < s[j].Age }
func (s Students) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func main() {
students := []Student{
{"c", 31},
{"a", 20},
{"b", 21},
{"d", 19},
}
fmt.Println(students)
sort.Sort(Students(students))
fmt.Println(students)
}
Completed
Done! we’ve seen how to define Slice and how to use it in Golang. Also, we’ve seen the difference between Array and Slice, and we’ve learned how to create Slice by slicing the Array.
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku
.Deku
created the applications with Flutter.If you have interested, please try to download them for free.