简记Go语言中的数组、切片、映射

2018-03-13

在适合的地方用适合的技术才是最酷的

数组

  • 数组是切片、映射的基础数据结构;
  • 长度固定建立后不能改变,用于存储一段相同类型的元素的连续块(占用内存连续分配,CPU缓存更持久);
  • 初始化有 固定数组长度(数据类型零值)、字面量初始化,使用“…”会根据字面量长度分配数组大小;
  • 指定特定长度数组
    Go:
    arr := [5]int{1:10,2:20}
  • 指针数组
    指针数组的赋值与使用:
    1
    2
    3
    arr := [5]*int{0:new(int),1:new(int)}
    *arr[0]=10
    *arr[1]=10

复制数组指针只会复制指针的值,并不会复制指向的值;

  • 多维数组略
  • 根据内存和性能来看,在函数之间传递数组会有很大开销,可以传入数组指针;

切片

  • 切片是一种便于使用管理基于数组的数据结构,围绕动态数组的概念构建,可以按照需求自动曾长或缩小;
  • 切片数据结构内部实现有:【指针】、【长度】、【容量】
  • 可以通过make或字面常量来创建切片,[]里面没有数量值得是切片,有数字(长度)的是数组;
  • nil和空切片在必要的时候很有用,比如函数返回(略);
  • 修改切片创建的切片会影响原切片(切片基于数组的值)
  • 计算长度和容量

    1
    2
    3
    eg. slice[i:j](容量是k)  
    长度:j - i
    容量:k - i (容量是到被切切片末尾的的)
  • 切片只能访问其长度内的元素,试图访问其超出长度的元素会导致运行时异常;

  • 函数append会增加新切片的长度,容量有可能改变(改变时会创建新的切片不影响原切片),有可能不改变(会修改原切片(包括原数组内容)),取决于切片的可用容量;
  • 函数append会智能滴处理底层数组的容量增长。切片容量在小于1000个元素时,总是会成倍的增长容量。一旦元素的个数超过1000,容量增长就会设置成1.25,随着语言的变化算法也会有所变化;
  • 创建切片的第三个索引是容量 slice := source[2:3:4]

    1
    2
    3
    slice[i:j:k]  
    长度:j-i
    容量:k-i
  • 如果试图设置比可用容量还大,就会得到运行时速度;

  • 切片时设置 长度和容量相同,新的append操作会创建新的底层数组使其与原有切边的底层数组分离;
  • append(s1,s2…)使用 … 可以将一个切片的所有内容添加到另一个切片中 ;
  • 关键字range可以配合for遍历切片中的元素,range会返回索引和值(副本,不是该元素发的引用),不要使用指针,不使用的内容可以使用_占位符;
  • len函数返回切片长度,cap函数返回切片容量;
  • 切片本身结构简单,传递开销小,适用于函数内外传递;
    … 未完待续

映射

  • 映射的结构相对复杂(用合理的算法高效率的完成需求);
  • 映射是一种数据结构,用于存储一系列无序的键值对;
  • 映射内部实现是一个集合,可以使用类似处理数组和切片的方式迭代映射中的元素,但映射是无需的集合,以为这没办法预测键值对被返回的顺序。即便使用相同的书序保存键值对,每次迭代映射的顺序也有可能不一样。无序的原因是映射的实现使用了散列表;
  • 具体可以搜索Go映射的相关知识;
  • 映射是一个存储键值对的无序集合
  • 可以用make字面量方式申明映射数据类型;

    1
    2
    dict := make(map[string]int)  
    dict := map[string]string{"Red":"#DA1337","Orange":"#E95A22"}
  • 映射更常用字面量方法,映射初始长度会根据初始化时指定的键值对的数量来确定;

  • 映射的键可以是任何可以用“==”进行值比较大(切片什么的会造成错误);
  • 可以创建空的键值对后添加内容;

    1
    2
    var colors map[string]string  
    colors["Red"]="#da1337"
  • 关于判断值是否存在,

    valie , exists := colors["Blue"]  
    if exists {  
      fmt.Println(value)  
    }  
    //或者  
    if value != ""{  
    //...  
    }  
    //go语言中,通过键来索引映射是,即便这个键不存在也会返回一个同类型的零值;
    
  • 迭代时可以使用 range迭代;
  • 可以用delete删除映射中的元素;
  • 同切片一样,传递函数的开销不大;

Kommentare: