mtchuyen / Golang-Tips

Tips in Golang programming
3 stars 2 forks source link

Golang - Basic - Array & Slice #8

Open mtchuyen opened 3 years ago

mtchuyen commented 3 years ago
https://golang.org/ref/spec#Slice_types:
A slice is a descriptor for a contiguous segment of an *underlying array* and provides access to a numbered sequence of elements from that array.

Error:

    var temp []int
    var n = 8

    temp = temp[:0] //truncate any prior cases
    for addendum := n / 2; addendum > 0; addendum-- {
        for _, item := range Q {
            temp = append(temp, append(item, addendum)) //--> Error here
        }
    }

Correct:

    for addendum := n / 2; addendum > 0; addendum-- {
        for _, item := range Q {
            z := make([]int, len(item), len(item)+1)
            copy(z, item)
            z = append(z, addendum)
            temp = append(temp, z)
        }
    }
mtchuyen commented 2 years ago

Note that arrays are rarely used in Go. When in doubt, default to using a slice.


Array:
// Create an array, intialized to the Zero Value
s2ArrayZeroVal := [2]Struct2{}
fmt.Println("s2ArrayZeroVal ", s2ArrayZeroVal)

// Create an array, intialized to a specific values
s2ArrayOtherVal := [2]Struct2{{Name: "foo", temp: Struct1{val1: 6, val2: 10}}, {Name: "bar", temp: Struct1{val1: 16}}}
fmt.Println("s2ArrayOtherVal ", s2ArrayOtherVal)

Slice (not fix size): 
// Create an slice, intialized to the Zero Value
s2SliceZeroVal := []Struct2{{}, {}}
fmt.Println("s2SliceZeroVal ", s2SliceZeroVal)

// Create an slice, intialized to a specific values
s2SliceOtherVal := []Struct2{{Name: "foo", temp: Struct1{val1: 6, val2: 10}}, {Name: "bar", temp: Struct1{val1: 16}}}
fmt.Println("s2SliceOtherVal ", s2SliceOtherVal)
mtchuyen commented 2 years ago

"append" in memory: addresses in memory was changed

https://groups.google.com/g/golang-nuts/c/riMkJmgsarI?pli=1

189. Rotate Array

func rotate(nums []int, k int) {

      for i := range nums{
            fmt.Println(&nums[i], nums[i])
      }

     nums = append(nums[len(nums) - k:], nums[:len(nums) - k]...)

     fmt.Println("-----------------------------------------")
     for i := range nums{
           fmt.Println(&nums[i], nums[i])
      }
}

Append is for appending items at the end of a slice. If there is enough space, Go will simply append the items and return the slice. If there is not enough space, Go will create a new slice with double the capacity of the existing slice or at least enough space to hold the new items (whichever is larger), copy the items, and return the new slice. In your case, when you first instantiate the slice, Go allocates just enough memory to hold the numbers. Then, in your append, Go checks whether "nums[len(nums) - k:]" has enough remaining capacity to hold the new items. Note that "nums[len(nums) - k:]" is a new slice and it has a shorter capacity than the original slice. Since there is not enough space, Go creates a new slice, copy the items, and returns the new slice. That is how you got the new slice.

mtchuyen commented 2 years ago

slices grow at 25% after 1024 but why 1024?

https://groups.google.com/g/golang-nuts/c/UaVlMQ8Nz3o?pli=1

package main

import (
    "fmt"
)

func main() {
    for i := 0; i < 2000; i += 100 {
        fmt.Println(i, cap(append(make([]bool, i), true)))
    }
}