# 03/02 Study Daily record

sjinsung·2022년 2월 3일
0

### Slice

• go.dev/blog/slices-intro
• slice consists of three things: a pointer to an array, length and capacity.
• nil and empty slices (with 0 capacity) are not the same, but their observable behavior is the same.
• The nil slice has 0 data pointer
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
• go.dev/play/p/QDcrCLRevyC
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
• Because d took a slices from 2, 4 capacities were allocated(from the start to the end of the array).
• It has access to the rest of the underlying array that it originally presented(a[0:5]).
• go.dev/play/p/aC_sZuihZcb
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]
• copy function returns qty of items copied
• changed s2[0] couldn't affect s1. because we used copy function.
var s = make([]int, 3)
n := copy(s, []int{0, 1, 2, 3}) // n == 3, s == []int{0, 1, 2}
• because s len is 3, so it cannot take more than 3.
• So n also took 3 as copied numbers.

Copy from a slice to itself

s := []int{0, 1, 2}
n := copy(s, s[1:]) // n == 2, s == []int{1, 2, 2}
• If copy itself, The last slice was allocated to the end.

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]
• subslice should have only s[1:4] = {2,3,4].

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]
• Triple dot converts slice to colletion of arguments.

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

### Code

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

### Code

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]`
Gopyther