Go Language Learning Notes (3) Array & Slice & map

Posted by calabiyau on Wed, 12 Jun 2019 19:21:10 +0200

Add Golang Learning QQ Group to Learn Progress, Start a Family and Start a Business Job ^-^ Group Number: 96933959

Arrays

Arrays are fixed-length sequences of the same data type.

The array is a value type, so changing the value of the copy does not change its own value.

When an incoming reference is introduced as a method, an array is copied instead of referring to the same pointer.

Access element values through subscript indexes starting at 0.

array define

var a []int
a = make([]int, 5)
var a1 [5]int = [5]int{1, 2, 3, 4, 5}      //len:5 content:[1 2 3 4 5]
var a2 = [5]int{1, 2, 3, 4, 5}             //len:5 content:[1 2 3 4 5]
var a3 = [...]int{1, 2, 3, 4, 5}           //len:5 content:[1 2 3 4 5]
var a4 = [...]int{1: 100, 2: 200}          //len:3 content:[0 100 200]
var a5 = [...]string{1: "nick", 2: "dawn"} //len:3 content:[ nick dawn]

After the array is defined, the length cannot be changed.

Length is a part of the array type. Arrays with different lengths have different types.

Therefore, var a[5] int and vara [9] int are different types.

Array usage

By subscription access, errors will be reported if exceeded

arr := [5]int{1, 2, 3}
//fmt.Println(arr[5])    //Report errors

Traversing array elements by for

func main()  {
    arr := [5]int{1, 2, 3}
    for i:=0; i<len(arr); i++ {
        fmt.Println(arr[i])    //12300
    }
    for i,v := range arr{
        fmt.Printf("index[%d]:content[%v]\n", i, v)
    }
}

Value type array assignment, changing the copy will not change itself

func main()  {
    arr := [5]int{1, 2, 3}
    arr2 := arr
    arr2[0] = 10
    fmt.Println(arr)    //[1 2 3 0 0]
    fmt.Println(arr2)    //[10 2 3 0 0]
}
package main

import (
    "fmt"
)

func test1(n int) {
    var a []int
    a = make([]int, n)

    a[0] = 1
    a[1] = 1

    for i := 2; i < n; i++ {
        a[i] = a[i-1] + a[i-2]
    }
    for _, v := range a {
        fmt.Println(v)
    }
}

func main() {
    test1(10)
}
Chestnut (Fibonacci sequence)

 

Two-dimensional arrays

Multidimensional arrays, two-dimensional arrays for example

var a1 [2][5]int

Two-dimensional array traversal

func main() {
    var a1 [2][5]int = [...][5]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}

    for row, v := range a1 {
        for col, v1 := range v {
            fmt.Printf("(%d,%d)=%d ", row, col, v1)
        }
        fmt.Println()
    }
}

 

Slices

Slices are the same sequence of elements with variable length and fixed capacity.

A slice is a reference to an array, so a slice is a reference type.

Therefore, the same pointer will be referenced when passing slices, and the modified value will affect other objects.

Slice is close to array, but can increase length when new elements are added. Slice always points to an array at the bottom. Slice itself is not an array, slice is a pointer to array.

Slice definition

The only difference between creating slices and creating arrays is whether there are numbers in "[]" before Type. If they are empty, they represent slices, otherwise they represent arrays.

s1 := [] int{1, 2, 3}          //Direct initialization slice,[]Representation is slice type,Initialization values are 1 in turn,2,3.his cap=len=3
s2 := arr[:]                   //Initialization slice s2,It's an array. arr Citation
s3 := arr[startIndex:endIndex] //take arr Subordinate Subscript startIndex reach endIndex-1 The following element is created as a new slice
s4 := arr[startIndex:]         //default endIndex The time will indicate up to arr The last element
s5 := arr[:endIndex]           //default startIndex This will indicate that from arr The first element begins
s6 := s1[startIndex:endIndex]  //By slicing s6 Initial slice interception s1
s7 := make([]int, len, cap)    //Through built-in functions make()Initialization slice s,cap Can be omitted(Ellipsis time,The value is equivalent to len)

len() and cap()

Length is the maximum subscript + 1 that has been assigned and can be obtained by the built-in function len().

Capacity refers to the maximum number of elements that can be accommodated by the slice at present, which can be obtained by the built-in function cap().

arr := [5]int{1, 2, 3}
fmt.Println(len(arr))    //5
fmt.Println(cap(arr))    //5

Slice use

Traversal and modification

for i, v := range slice0 {
    slice0[i] = strings.ToUpper(v)
    fmt.Printf("index[%d]content[%s,%s]\n", i, v, slice0[i])
}

append and copy

Append operation: slice can append elements to the tail, or even one slice to the tail of another slice. If the final length does not exceed the original slice, the append operation will return to the original slice, otherwise the memory address will be reallocated.

Copy operation: The copy operation returns the number of elements copied, which is the smallest value in len(src) and len(dst).

slice := []int{1, 2}
fmt.Printf("len[%d],content:%v\n", len(slice), slice) //len[2],content:[1 2]
slice = append(slice, 5, 6, 8, 9)
fmt.Printf("len[%d],content:%v\n", len(slice), slice) //len[6],content:[1 2 5 6 8 9]

slicecp := make([]int, len(slice))
fmt.Printf("len[%d],content:%v\n", len(slice), slice) //len[6],content:[1 2 5 6 8 9]
n := copy(slicecp, slice)
fmt.Printf("len[%d],content:%v, retN:%d\n", len(slice), slice, n) //len[6],content:[1 2 5 6 8 9], retN:6
slicecp[0] = 10
fmt.Printf("len[%d],content:%v\n", len(slice), slice)     //len[6],content:[1 2 5 6 8 9]
fmt.Printf("len[%d],content:%v\n", len(slicecp), slicecp) //len[6],content:[10 2 5 6 8 9]

sliceN := append(slice, slicecp...)
fmt.Printf("len[%d],content:%v\n", len(sliceN), sliceN)    //len[12],content:[1 2 5 6 8 9 10 2 5 6 8 9]

Value type modifications affect the value itself.

slice0 := []string{"a", "b", "c", "d", "e"}
slice1 := slice0
slice1[0] = "Nick"
fmt.Println(slice0)    //[Nick b c d e]
fmt.Println(slice1)    //[Nick b c d e]

 

Memory Layout and Expansion

Slice is a reference type, pointer interior only to an array.

Code implementation, memory address is the same address.

func main() {
    var a []int = []int{1, 2, 3, 4, 5}
    s := a[1:]
    fmt.Printf("a=%p, s=%p \n", &(a[1]), s) //a=0xc420016188, s=0xc420016188
    s = append(s, 10, 10, 10)
    fmt.Printf("a=%p, s=%p \n", &a[1], s)   //a=0xc420016188, s=0xc4200141c0
}

The length of the slice is variable. What is the mechanism of automatic expansion?

It's double (double). Look at the code below.

func main() {
    var a [5]int = [...]int{1, 2, 3, 4, 5}
    s := a[1:]
    fmt.Println(cap(s), len(s)) //4 4
    s = append(s, 10, 10, 10)
    fmt.Println(cap(s), len(s)) //8 7
    s = append(s, 10)
    fmt.Println(cap(s), len(s)) //8 8
    s = append(s, 10)
    fmt.Println(cap(s), len(s)) //16 9
    s = append(s, 10, 10, 10, 10)
    fmt.Println(cap(s), len(s)) //16 13
    s = append(s, 10, 10, 10, 10, 10, 10)
    fmt.Println(cap(s), len(s)) //32 19
}
package main

import (
    "fmt"
)

type slice struct {
    pre *[100]int
    len int
    cap int
}

func make1(s slice, cap int) slice {
    s.pre = new([100]int)
    s.len = 0
    s.cap = cap
    return s
}

func modify(s slice) {
    s.pre[1] = 1000
}

func testSlice() {
    var s1 slice
    s1 = make1(s1, 10)

    s1.pre[0] = 100
    modify(s1)

    fmt.Println(s1.pre)
}

func main() {
    testSlice()
}
Mimic slice

 

map

map exists as a built-in type in Go.

The data structure of key-value is also called dictionary or associative array.

map is a reference type.

The map declaration does not allocate memory and requires make initialization.

map declaration initialization

statement

var a map[keytype]valuetype
var a map[string]string
var a map[string]int
var a map[int]string
var a map[string]map[string]string  //nesting

Declare and initialize

var a map[string]string
a = make(map[string]string, 10)

a := make(map[string]string, 10)
a := make(map[string]string)

var a map[string]string = map[string]string{}
var a map[string]string = map[string]string{
    "A": "A",  //Notice that it's a comma.
}

 

map usage

crud

m["name"] = "Nick"   // "create"
delete(m, "name")    // "delete"
m["name"] = "Dawn"   // "update"
name := m["name"]    // "read"

Read no exceptions

name, errbool := m["name"]
if !errbool {
    m["name"] = "Nick"
}

Two-dimensional map

func modify(a map[string]map[string]string) {
    _, ok := a["name"]
    if !ok {
        a["name"] = make(map[string]string)
    }
    a["name"]["Nick"] = "suoning"
    a["name"]["Nicky"] = "manyRou"
}

func testMap3() {
    var a map[string]map[string]string
    a = make(map[string]map[string]string, 10)    //Initialization of one dimension
    a["name"] = make(map[string]string)           //Initialization of 2-D

    modify(a)
    fmt.Println(a)
}

 

slice of map

Items := make([]map[int][int], 5)
For i := 0; i < 5; i++ {
        items[i] = make(map[int][int])
}

 

map sort

  1. Get all the key s first and sort them.
  2. Traverse by sorted key
import "sort"

func testMapSort() {
    var a map[int]int
    a = make(map[int]int, 5)

    a[8] = 10
    a[5] = 10
    a[2] = 10
    a[1] = 10
    a[9] = 10

    var keys []int
    for k, _ := range a {
        keys = append(keys, k)
    }

    sort.Ints(keys)

    for _, v := range keys {
        fmt.Println(v, a[v])
    }
}

 

map inversion

Initialize another map and swap key and value

func testMapSort1() {
    var a map[string]int
    var b map[int]string

    a = make(map[string]int, 5)
    b = make(map[int]string, 5)

    a["name"] = 53
    a["ege"] = 10

    for k, v := range a {
        b[v] = k
    }

    fmt.Println(b)
}

Topics: Go