Go基础教程-容器

栏目: Node.js · 发布时间: 6年前

  • go 容器: 数组(Array) 、切片(Slice)、映射(map)

数组 Array

  • 数组:是一个长度固定,用于存储一段具有相同类型元素的连续块。 在 Go 开发中一般不直接使用数组,而是使用切片,数组是定长的,不可扩展,切片相当于动态数组,使用场景多。

  • exaple:

func definedArray() {
   var arr1 [3]int // [0 0 0]  声明数组,不赋初值(使用默认值)
   arr2 := [3]int{1, 2, 3} // [1 2 3]// 字面量声明数组,赋初值
   arr3 := [...]int{4, 5, 6, 7} // [4 5 6 7] // 容量由初始化值的数量决定,...不可省略,不带长度或者 ... 的表示切片
   arr1[0] = 1
   fmt.Println(arr1[0])
   fmt.Println(arr1, arr2, arr2)
   //数组间的相互赋值
   只有数组的类型相同,容量一样,两个数组才能相互赋值
   arr1 = arr2 //正确
   arr1 = arr3 //错误
}

切片

  • 切片是一种数据结构,这种数据结构便于管理数据集合。切片是围绕动态数组的概念构建的,可以按需自动增长和缩小。切片的动态增长是通过内置函数 append 来实现的。这个函数可以快速且高效地增长切片。还可以通过对切片再次切片来缩小一个切片的大小。

  • 切片是一个很小的对象,对底层数据进行了抽象,并提供相关的操作方法。切片有三个字段:分别是指向底层数组的指针、切片访问的元素的个数(即长度)和切片允许增长到的元素个数(即容量) Go基础教程-容器

  • 切片共享底层数据

  • example:

func definedSlice() {
    slice1 := make([]int, 5) // 创建一个整型,容量、长度为5的切片
    slice2 := make([]string, 3, 5) // 创建一个整型,容量为5,长度为3的切片
    slice3 := []string{"oc", "pyhton", "js", "go", "nodeJS"}  //  切片字面量声明切片
    var slice4 []int //创建nil整型切片
    slice5 := make([]int, 0) //使用make创建整型nil切片
    slice6 := slice3[0:] //"oc", "pyhton", "js", "go", "nodeJS"
    slice7 := slice6[2:4] //"js", "go"
    slice8 := slice6[:] //"oc", "pyhton", "js", "go", "nodeJS"
}
  • 切片的长度和容量
对底层数组容量为k的切片 slice[i:j]
长度:j - i
容量:k - j
或者
slice := souce[i:j:k]
i < j < k
长度:j - i
容量:k - i
  • 对切片的操作
#append 增加切片长度
slice := []int {10, 20 , 30, 40, 50}
newSlice := slice[2:4] // 30, 40
newSlice = append(newSlice, 45)
fmt.Println(slice) //10, 20 , 30, 40, 45
fmt.Println(newSlice) //30, 40, 45
newSlice = append(newSlice, 55)
fmt.Println(cap(newSlice)) // 6
newSlice[0] = 0
fmt.Println(slice) //10, 20 , 30, 40, 45
fmt.Println(newSlice) //0, 40, 45, 55
  • 切片共享数组底层数据 Go基础教程-容器
  • 当切片没有足够的可用容量,再追加需要扩容,此处会新建一个新的底层数组newSlice,然后将旧数组元素拷贝到新数组,而 slice 的底层数组是旧数组,此时二者互不影响;
  • slice 扩容机制:在切片的容量小于 1000 个元素时,总是会成倍地增加容量。一旦元素个数超过 1000,容量的增长因子会设为 1.25,也就是会每次增加 25% 的容量

切片引发的问题

  • 由于切片共享底层数据,所以我们对切片的修改可能会影响多个切片,却很难找到问题的原因
slice := []int {10, 20 , 30, 40, 50}
newSlice := slice[2:4] // 30, 40
newSlice = append(newSlice, 45) //原有slice也做了修改
fmt.Println(slice) //10, 20 , 30, 40, 45
fmt.Println(newSlice) //30, 40, 45

解决途径

  • 创建切片时设置长度和容量一样,当我们对切片append的时候会创建一个新的底层数组,与原有的底层数组分离,这样就可以安全的进行后续修改。

  • 切片合并

slice1 := []string{"oc", "nodeJS"}
slice2 := []string{"go", "pthon"}
slice3 := append(slice1, slice2...)
fmt.Println(slice3) //[oc nodeJS go pthon]
  • 切片迭代
slice := []string{oc,nodeJS, go, pthon}
for index, value := rang slice {
  fmt.Println(index, value)
}

Map 映射

  • 映射是一种数据结构,用于存储一些列无需的键值对。
func definedMap() {
    // 1、使用 make 创建 map,key为string,value为string
    map1 := make(map[string] sring)
    // 2、使用字面量创建 map - 最常用的姿势,key为string,value为slice,初始值中的slice可以不加 []string 定义
    map2 := map[string][]string{"hi": {"go", "c"}, "hello": []string{"java"}}
    // 3、创建空映射
    map3 := map[string]string{} // map3 := map[string]string nil映射
    fmt.Println(map1, map2, map3)
}
  • 对映射对操作
#增加
lessons := map[string]string {"name1":"oc", "name2":"python"}
lessons["name3"] = "go"// 增加name3
#删除
delete(lessons, "name1")// 删除 name1
#取值
value, exist := lessons["name1"]
if exist {
    fmt.Println(value)
} else {
    fmt.Println("lessons[\"name1\"] does not exist")
}
#迭代
for key, value := rang lessons {
    fmt.Println(key, value)
}

以上所述就是小编给大家介绍的《Go基础教程-容器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Web Designer's Idea Book, Vol. 2

The Web Designer's Idea Book, Vol. 2

Patrick McNeil / How / 2010-9-19 / USD 30.00

Web Design Inspiration at a Glance Volume 2 of The Web Designer's Idea Book includes more than 650 new websites arranged thematically, so you can easily find inspiration for your work. Auth......一起来看看 《The Web Designer's Idea Book, Vol. 2》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码