s := []int{3,4,5} // Initialize with values
s := []int{} // Initialize but with no values, memory is allocated
var s []int // Declare a slice but don't allocated memory just yet
s := make([]int,5,10) // Initialize with no values, allocate memory, specify the length of the slice and the capacity of the underlying array
Print result
[3 4 5]
[]
[]
[0 0 0 0 0]
Check length and capacity and Nil
fmt.Println("s[] length:", len(s), "Capacity:", cap(s), "Nil:", nilchecker(s))
fmt.Println("t[] length:", len(t), "Capacity:", cap(t), "Nil:", nilchecker(t))
fmt.Println("u[] length:", len(u), "Capacity:", cap(u), "Nil:", nilchecker(u))
fmt.Println("v[] length:", len(v), "Capacity:", cap(v), "Nil:", nilchecker(v))
}
func nilchecker(s []int) bool {
if s == nil {
return true
} else {
return false
}
}
Print result
s[] length: 3 Capacity: 3 Nil: false
t[] length: 0 Capacity: 0 Nil: false
u[] length: 0 Capacity: 0 Nil: true
v[] length: 5 Capacity: 10 Nil: false
func main() {
a := []int{1, 2, 3, 4, 5, 6}
b := a[2:4]
c := a[:3]
d := a[3:]
fmt.Println("Slices a: ", a, " b:", b, " c:", c, " d:", d)
fmt.Println("Capacity of b:", cap(b))
}
Print result
Slices a: [1 2 3 4 5 6] b: [3 4] c: [1 2 3] d: [4 5 6]
Capacity of b: 4
func main() {
s1 := []int{1, 2, 3, 4, 5, 6}
fmt.Println("s1:", s1)
s2 := s1[2:4]
s2[0] = 10
fmt.Println("s1:", s1)
}
Print result
s1: [1 2 3 4 5 6]
s1: [1 2 10 4 5 6]
- go.dev/play/p/_HJ04t2rP-L
- This is because, unlike an array, a slice does not copy a value, but refers to the address value referenced by the slice itself. But in the same situation, the array is initialized by simply copying the values
```go
func main() {
s1 := []int{1, 2, 3, 4, 5, 6}
fmt.Println("s1:", s1)
s2 := make([]int, 2)
n := copy(s2, s1[2:4])
fmt.Println("Number of items copied: ", n)
s2[0] = 10
fmt.Println("s1:", s1)
fmt.Println("s2:", s2)
}
s1: [1 2 3 4 5 6]
Number of items copied: 2
s1: [1 2 3 4 5 6]
s2: [10 4]
var s = make([]int, 3)
n := copy(s, []int{0, 1, 2, 3}) // n == 3, s == []int{0, 1, 2}
Copy from a slice to itself
s := []int{0, 1, 2}
n := copy(s, s[1:]) // n == 2, s == []int{1, 2, 2}
Memory leaking
func main() {
subslice := testSubSlice()
fmt.Println(subslice, " length: ", "remaining underlying array: ", subslice[:cap(subslice)])
}
func testSubSlice() []int {
s := []int{1, 2, 3, 4, 5, 6, 8, 9, 10}
return s[1:4]
}
Print result
[2 3 4] length: remaining underlying array: [2 3 4 5 6 8 9 10]
Prevent leaking memory by using copy function
func main() {
subslice := testSubSlice()
fmt.Println(subslice, " length: ", "remaining underlying array: ", subslice[:cap(subslice)])
}
func testSubSlice() []int {
s := []int{1, 2, 3, 4, 5, 6, 8, 9, 10}
sub := make([]int, 3)
copy(sub, s[1:4])
return sub
}
Print result
[2 3 4] length: remaining underlying array: [2 3 4]
func main() {
s1 := []int{1, 2, 3}
s1 = append(s1, 4, 5, 6)
s2 := []int{7, 8, 9}
s1 = append(s1, s2...)
fmt.Println(s1)
}
Print result
[1 2 3 4 5 6 7 8 9]
Slice tricks
-remove items => a = append(a[:i], a[j:]...)
-remove one item => a = append(a[:i], a[i+1]...)
-Cut if the slice contains pointers:copy(a[i:], a[j:]) for k, n := len(a)-j+i, len(a); k<n; k++ { a[k] = nil // or the zero value of T } a = a[:len(a)-j+i]
-Delete if the slice contains pointers: a, a[len(a)-1] = append(a[:i]. a[i+1]...), nil
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
i := 2
j := 4
copy(a[i:], a[j:])
fmt.Println(a, len(a))
for k, n := len(a)-j+i, len(a); k < n; k++ {
a[k] = 0 // or the zero value of T
}
a = a[:len(a)-j+i]
fmt.Println(a, len(a))
}
[1 2 5 6 7 8 9 10 9 10] 10
[1 2 5 6 7 8 9 10] 8
func main() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
a = append(a[:2], a[4:]...)
fmt.Println(a)
}
[1 2 5 6 7 8 9 10]