「Golang成長之路」內建容器篇

yangkuang發表於2021-06-02

一、陣列(Array)

陣列:陣列是指有序的元素序列。如果將有限個型別相同的變數的集合命名,那麼這個名稱就是陣列名,而組成陣列的各個變數稱為陣列的分量,也稱為陣列的元素,有時也稱為下標變數,而陣列中的資料可以使用下標(索引)來查詢到。

其實在程式語言中陣列的概念是一樣的,下面具體來看看golang中陣列是如何定義和使用的:
1.陣列的定義

  • 方法一:

    var arr1 [5]int   //定義一個擁有5個元素的陣列,此時元素全為0
  • 方法二:

    arr2 := [5]int{0, 1, 2, 3, 4}     //定義並放入值
  • 方法三:

    arr3 := [...]int{0, 1, 2, 3, 4} //用[...],此時不需寫入陣列空間具體是多少
  • 二維陣列的定義:

    package main
    import "mft"
    func main {
    //二維素組
    var arr4 [4][5]int
    fmt.Println(arr4)
    }

    輸出為:

    [[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

2.陣列的使用

  • 遍歷
    package main
    import "fmt"
    arr :=[...]int{0, 1, 2, 3, 4}
    for i := range arr{
      fmt.Println(arr[i])
    }
    輸出為:
    0
    1
    2
    3
    4
    也可以這樣遍歷:
    //.陣列的遍歷
    for i,v :=  range arr3{   //i為對應元素的索引值,v為元素值
         fmt.Println(i, v)
    }
    輸出為:
    0 0
    1 1
    2 2
    3 3
    4 4
  1. 改變元素的值
    arr :=[...]int{0, 1, 2, 3, 4}
    arr[0] = 100  //將arr[0]改為100
    fmt.Println(arr)
    arr[0] = 0  //將arr[0]改回0
    fmt.Println(arr)
    輸出為:
    [100 1 2 3 4 ]
    [0 1 2 3 4 ]
  • 陣列的值傳遞
    陣列的值傳遞仍然是將整個陣列copy一份傳入函式,不會改變arr的值

    //陣列的值傳遞
    package main
    import "fmt"
    //定義函式:
    func printarr1(arr [5]int){
      arr[0] = 100
      fmt.Println(arr)
    }
    func main{
      printarr1(arr)
      fmt.Println(arr)
    }

    輸出為:

    [0 1 2 3 4 ]
  • 使用指標
    使用指標是將陣列的相應值的地址傳入函式

    //使用指標
    package main
    import "fmt"
    //定義函式:
    func printarr2(arr *[5]int) {
      arr[0] = 100
      fmt.Println(arr)
    }
    func main{
      printarr2(&arr3)
      fmt.Println(arr3)
    }

    輸出為:

    [100 1 2 3 4]

二、切片(Slice)

切片是golang中重要操作之一
直接看操作:

package main
import main
func main{
//切片
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s := arr[2:6]
fmt.Println("s = ",s)
fmt.Println("arr[2:6 =",arr[2:6])
fmt.Println("arr[:6] = ",arr[:6])
fmt.Println("arr[2:] = ",arr[2:])
fmt.Println("arr[:] = ",arr[:])
}

輸出為:

s =  [2 3 4 5]
arr[2:6 = [2 3 4 5]
arr[:6] =  [0 1 2 3 4 5]
arr[2:] =  [2 3 4 5 6 7]
arr[:] =  [0 1 2 3 4 5 6 7]
  1. Slice值的改變
    改變Slice中元素的值,會導致底層arr值的改變
    package main
    import m="fmt"
    //定義函式,改變Slice的值
    //切片
    func updateSlice(s []int){
       s[0] = 100
    }
    //主函式
    func main{
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    s1 :=arr[2:]
    s2 := arr[:]
    //改變之前
    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println("change after:")
    //函式呼叫
    updateSlice(s1)
    fmt.Println(s1)
    //最後底層的arr的值也會隨之改變
    fmt.Println(arr)
    }
    輸出為:
    [2 3 4 5 6 7]
    [0 1 2 3 4 5 6 7]
    change after:
    [100 3 4 5 6 7]
    [0 1 100 3 4 5 6 7]
    現在我們再來改變S2:
    fmt.Println(s2)
    updateSlice(s2)
    fmt.Println(s2)
    fmt.Print(arr)
    輸出為:
    [0 1 100 3 4 5 6 7]
    [100 1 100 3 4 5 6 7]
    [100 1 100 3 4 5 6 7]

這裡還有一種情況:Slice的更新

package main

import "fmt"

func main{

arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s2 := arr[:]
//Slice中值的更新
//對Slice的操作,其實是對底層arr的修改

fmt.Println(s2)
s2 = s2[:5]
fmt.Println(s2)
s2 = s2[2:]
fmt.Println(s2)
fmt.Println(arr)

輸出為:

[0 1 2 3 4 5 6 7]
[0 1 2 3 4]
[2 3 4]
[0 1 2 3 4 5 6 7]
  1. Slice的擴充套件
    先來看一個例子:
    //Slice的擴充套件
    package main
    import "fmt"
    func main{
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    fmt.Println("Extneding Slice:")
    fmt.Println(arr)
    s1 = arr[2:6]
    s2 = s1[3:5]
    fmt.Println(s1)
    fmt.Println(s2)
    fmt.Println(arr)
    }
    現在肯定對這段程式碼有疑問吧!
    s2 = s1[3:5] 會不會報錯?
    答案:不會!
    下面來看看執行結果:
    [0 1 2 3 4 5 6 7]
    [2 3 4 5]
    [5 6]
    [0 1 2 3 4 5 6 7]

*原因:在golang中Slice是可是往後擴充套件的,例如上面
arr := […]int{0, 1, 2, 3, 4, 5, 6, 7}
s1 = arr[2:6] = [2 3 4 5]
s2 = s1[3:5],此時已經超出s1的範圍了,但是Slice是對底層arr的操作,並且可以往後擴充套件的,所以往底層走就應該是[5 6],s2 = s1[3:5] = [5 6] *

  1. 向slice新增元素
    向slice新增元素使用append(s, x)

    //向slice新增元素
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    //切分
    s1 :=arr[2:]
    s2 := arr[:]
    //列印
    fmt.Println(s1)
    fmt.Println(s2)
    //新增元素
    s3 := append(s2, 10)
    s4 := append(s3, 11)
    s5 := append(s4, 12)
    fmt.Println("s3, s4, s5 =",s3, s4, s5)
    fmt.Println("arr = ",arr)

    輸出為:

    [2 3 4 5 6 7]
    [0 1 2 3 4 5 6 7]
    s3, s4, s5 = [0 1 2 3 4 5 6 7 10] [0 1 2 3 4 5 6 7 10 11] [0 1 2 3 4 5 6 7 10 11 12]
    arr =  [0 1 2 3 4 5 6 7]  //arr的容量已經固定,不會變
  2. slice的建立

  • 1
    package mian
    import "fmt"
    //定義函式
    func printslice(s []int){
     fmt.Printf(" s=%v, len=%d, cap=%d",s, len(s), cap(s))
    }
    func main{
    var s []int
    //s的初始化,生成100個奇數
    for i:=0; i < 100; i++{
       printslice(s)
       fmt.Print("\n")
       s = append(s, 2*i + 1)
    }
    }
  • 2
    package main
    import "fmt"
    //定義函式
    func printslice(s []int){
     fmt.Printf(" s=%v, len=%d, cap=%d",s, len(s), cap(s))
    }
    func main{
    //graet slice
    s1 := []int{0,1,2}
    s2 := make([]int, 16)
    s3 := make([]int, 10, 32)
    //呼叫函式
    printslice(s1)
    printslice(s2)
    printslice(s3)
    }
    輸出為:
    s=[0 1 2], len=3, cap=3
    s=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], len=16, cap=16
    s=[0 0 0 0 0 0 0 0 0 0], len=10, cap=32
  1. copy Slice
    //copy slice
    copy(s2, s1)   //將s1的內容copy到s2上
    fmt.Println(s2)
  2. delete Slice
    刪除操作
    package main
    import "fmt"
    定義函式
    func printslice(s []int){
    fmt.Printf(" s=%v, len=%d, cap=%d",s, len(s), cap(s))
    }
    //主函式
    func main{
    //delete "2"
    s5 := []int{0, 1, 2, 3, 4, 5, 6, 7}
    s5 = append(s5[:2], s5[3:]...)  //使用切片(Slice)
    printslice(s5)
    //delete front
    s5 = s5[1:]
    printslice(s5)
    //delete tail
    s5 = s5[:len(s5)-1]
    printslice(s5)
    輸出為:
    s=[0 1 3 4 5 6 7], len=7, cap=8
    s=[1 3 4 5 6 7], len=6, cap=7
    s=[1 3 4 5 6], len=5, cap=7

三、Map

map:是一個無序,key—value對,不會出現某個key對應不同的value

  • map的定義:

    //定義map
    m :=  map[string]string{      //[string]對應key,string對應value
     "name":"yangkuang",
    "work":"students",
    "year": "20",
    }
    m3 := map[string]int{
      "a": 0,
    "b": 1,
    "c": 2,
    
    //空map的定義
    m1 := make(map[string]int)   // empty map1
    var m2 map[string]int
    fmt.Println(m, m1, m2)    //map2 == nil

    輸出為:

    map[name:yangkuang work:students year:21] map[] map[]
  • map的遍歷
       for k, v := range m3{
           fmt.Println(k, v)
       }
    輸出為:
    a 0
    b 1
    c 2
  • map的查詢
    func main{
    //定義map
    m :=  map[string]string{
     "name":"yangkuang",
    "work":"students",
    "year": "21",
    }
    iname, ok := m["name"]   //key—name存在則將key對應的value賦值給iname,並且將ok賦值為true,否則ok為false
    fmt.Println(iname,ok)   //輸出:yangkuang true
    }
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章