Golang: 内建容器

chao2016 · · 616 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chao2016/article/details/81537007

内建容器有数组和Map
这里讲三个概念:数组、切片、Map

1. 数组

数组是值类型

  1. [10]int和[20]int是不同的类型
  2. 调用func f(arr [10]int)会拷贝数组。想改变原数组的值,用指针类型参数
  3. golang一般不直接使用数组

arrays.go:

package main

import "fmt"

func printArray(arr *[5]int)  {
    arr[0] = 100
    for i, v := range arr {
        fmt.Println(i, v)
    }
}

func main() {
    var arr1 [5]int
    arr2 := [3]int{1, 3, 5}
    arr3 := [...]int{2, 4, 6, 8, 10}
    var grid [4][5]int  // 多维数组,4个长度为5的int数组
    // 打印数组
    fmt.Println(arr1, arr2, arr3)
    fmt.Println(grid)
    // 遍历数组
    for i:= 0; i < len(arr3); i++ {
        fmt.Print(arr3[i])
    }
    fmt.Println()
    // 遍历数组可以用range关键字
    // 获得下标
    for i := range arr3 {
        fmt.Print(arr3[i])
    }
    fmt.Println()
    // 获得值
    for _, v := range arr3 {
        fmt.Print(v)
    }
    fmt.Println()
    // 获得数组下标和值
    for i, v := range arr3 {
        fmt.Println(i, v)
    }
    fmt.Println("printArray(arr1):")
    printArray(&arr1)
    fmt.Println("printArray(arr3):")
    printArray(&arr3)
    fmt.Println("arr1 and arr3:")
    fmt.Println(arr1, arr3)

}

输出:

[0 0 0 0 0] [1 3 5] [2 4 6 8 10]
[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
246810
246810
246810
0 2
1 4
2 6
3 8
4 10
printArray(arr1):
0 100
1 0
2 0
3 0
4 0
printArray(arr3):
0 100
1 4
2 6
3 8
4 10
arr1 and arr3:
[100 0 0 0 0] [100 4 6 8 10]

2. 切片(Slice)

2.1 slices.go:

package main

import "fmt"

func updateSlice(s []int)  {
    s[0] = 100
}

func main() {
    arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
    fmt.Println("arr[2:6] =", arr[2:6])
    fmt.Println("arr[:6] =", arr[:6])
    s1 := arr[2:]
    fmt.Println("arr[2:] =", s1)
    s2 := arr[:]
    fmt.Println("arr[:] =", s2)
    fmt.Println()

    fmt.Println("After updateSlice(s1):")
    updateSlice(s1)
    fmt.Println(s1)
    fmt.Println(arr)
    fmt.Println()

    fmt.Println("After updateSlice(s2):")
    updateSlice(s2)
    fmt.Println(s2)
    fmt.Println(arr)
    fmt.Println()

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

    fmt.Println("Extending slice")
    arr[0], arr[2] = 0, 2
    s1 = arr[2:6]
    s2 = s1[3:5]  // 取的[s1[3], s1[4]]
    //fmt.Println(s1[4])  // 会报错
    fmt.Println("s1 =", s1)
    fmt.Println("s2 =", s2)
    fmt.Println()

    // slice可以向后扩展,不可以向前扩展
    // s[i]不可以超越len(s),向后扩展不可以超越底层数组cap(s)
    fmt.Println("arr =", arr)
    fmt.Printf("s1 = %v, len(s1) = %d, cap(s1) = %d\n",
        s1, len(s1), cap(s1))
    fmt.Printf("s2 = %v, len(s2) = %d, cap(s2) = %d\n",
        s2, len(s2), cap(s2))
    fmt.Println()

    s3 := append(s2, 10)
    s4 := append(s3, 11)
    s5 := append(s4, 12)
    fmt.Println("s3, s4, s5 =", s3, s4, s5)
    // s4和s5不再是arr的view
    // 添加元素时如果超越cap,系统会重新分配更大的底层数组
    fmt.Println("arr =", arr)
}

输出:

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]

After updateSlice(s1):
[100 3 4 5 6 7]
[0 1 100 3 4 5 6 7]

After updateSlice(s2):
[100 1 100 3 4 5 6 7]
[100 1 100 3 4 5 6 7]

Reslice:
[100 1 100 3 4 5 6 7]
[100 1 100 3 4]
[100 3 4]
Extending slice
s1 = [2 3 4 5]
s2 = [5 6]

arr = [0 1 2 3 4 5 6 7]
s1 = [2 3 4 5], len(s1) = 4, cap(s1) = 6
s2 = [5 6], len(s2) = 2, cap(s2) = 3

s3, s4, s5 = [5 6 10] [5 6 10 11] [5 6 10 11 12]
arr = [0 1 2 3 4 5 6 10]

2.2 sliceops.go:

package main

import "fmt"

func printSlice(s []int)  {
    fmt.Printf("%v\n len=%d, cap=%d\n", s, len(s), cap(s))
}

func main() {
    fmt.Println("Creating slice:")
    var s []int  // Zero value for slice is nil
    for i := 0; i < 100; i++ {
        s = append(s, 2*i+1)
    }
    fmt.Println(s)

    s1 := []int{2, 4, 6, 8}
    printSlice(s1)

    s2 := make([]int, 16)
    printSlice(s2)

    s3 := make([]int, 10, 32)
    printSlice(s3)

    fmt.Println("Copying slice:")
    copy(s2, s1)
    printSlice(s2)

    fmt.Println("Deleting elements from slice:")
    s2 = append(s2[:3], s2[4:]...)
    printSlice(s2)

    fmt.Println("Popping from front:")
    front := s2[0]
    s2 = s2[1:]
    fmt.Println(front)
    printSlice(s2)
    fmt.Println("Popping from back:")
    tail := s2[len(s2) - 1]
    s2 = s2[:len(s2) - 1]
    fmt.Println(tail)
    printSlice(s2)
}

输出:

Creating slice:
[1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99]
[2 4 6 8]
 len=4, cap=4
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
 len=16, cap=16
[0 0 0 0 0 0 0 0 0 0]
 len=10, cap=32
Copying slice:
[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0]
 len=16, cap=16
Deleting elements from slice:
[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0]
 len=15, cap=16
Popping from front:
2
[4 6 0 0 0 0 0 0 0 0 0 0 0 0]
 len=14, cap=15
Popping from back:
0
[4 6 0 0 0 0 0 0 0 0 0 0 0]
 len=13, cap=15

3. Map

map的操作:

  1. 创建:make(map[string]int)
  2. 获取元素:m[key]
  3. key不存在时,获得Value类型的初始值
  4. 用value, ok:=m[key]来判断是否存在key
  5. 用delete删除一个key
  6. 使用len获得元素个数

map的遍历:

  1. 用range遍历key,或者遍历key-value对
  2. 不保证遍历顺利,如需顺序,需手动对key排序

map的key:

  1. map使用哈希表,必须可以比较相等
  2. 除了slice,map,function的内建类型都可以作为key
  3. Struct类型不包含上述三个字段,也可作为key

maps.go:

package main

import "fmt"

// map的操作
// 1. 创建:make(map[string]int)
// 2. 获取元素:m[key]
// 3. key不存在时,获得Value类型的初始值
// 4. 用value, ok:=m[key]来判断是否存在key
// 5. 用delete删除一个key
// 6. 使用len获得元素个数

// map的遍历
// 1. 用range遍历key,或者遍历key-value对
// 2. 不保证遍历顺利,如需顺序,需手动对key排序

// map的key
// 1. map使用哈希表,必须可以比较相等
// 2. 除了slice,map,function的内建类型都可以作为key
// 3. Struct类型不包含上述三个字段,也可作为key

func main() {
    fmt.Println("Creating map:")
    m := map[string]string {
        "name": "chao",
        "course": "golang",
        "site": "aliyun",
        "qualicty": "notbad",
    }
    m2 := make(map[string]int)  // m2 == empty map
    var m3 map[string]int  // m3 == nil,go的nil与其他语言的None不同,它可以进行计算

    fmt.Println(m)
    fmt.Println(m2)
    fmt.Println(m3)
    fmt.Println()

    // hashmap,key值是无序的
    fmt.Println("Traversing map:")
    for k, v := range m {
        fmt.Println(k, v)
    }
    fmt.Println()

    fmt.Println("Getting values:")
    courseName := m["course"]
    fmt.Println(courseName)
    causeName, ok := m["cause"]
    fmt.Println(causeName, ok)  // key不存在时,获得Value类型的初始值
    if causeName, ok = m["cause"]; ok {
        fmt.Println(causeName)
    } else {
        fmt.Println("key does not exist")
    }
    fmt.Println()

    fmt.Println("Deleting values:")
    name, ok := m["name"]
    fmt.Println(name, ok)

    delete(m, "name")
    name, ok = m["name"]
    fmt.Println(name, ok)
}

输出:

Creating map:
map[name:chao course:golang site:aliyun qualicty:notbad]
map[]
map[]

Traversing map:
name chao
course golang
site aliyun
qualicty notbad

Getting values:
golang
 false
key does not exist

Deleting values:
chao true
 false

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:chao2016

查看原文:Golang: 内建容器

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

616 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传