Go数据类型 slice map

一.切片(Slice)

  go语言中切片(Slice)和数组长的很像,可以把切片看做是对数组的一层简单的封装,在每个slice的底层数据结构中一定会包含一个数组。所以slice的功能是强大的,拥有数组的特性及slice本身所扩展的一些特性。

  看下面一个例子认识下slice

arr := [...]int{0,1,2,3,4,5,6,7,8}  //arr是数组
s := arr[2:6]                //这里s就是一个slice

 

   slice与数组的区别:

    1. go语言数组的长度不可改变,长度定义好之后,就不能再更改了,而slice非常灵活,可以动态扩容。

    2. slice 的底层数据是数组,slice是对数组的封装。

 

slice的声明

   var identifier []typeidentifier表示变量名,type表示切片中的元素类型,切片不需要说明长度。

   例如:

var a []string              //声明一个字符串切片
var b = []int{}             //声明一个整型切片并初始化
var c = []bool{false, true} //声明一个布尔切片并初始化

    

slice使用

   切片定义完之后,还不能使用,因为本身还是空的,是一个nil slice,需要让其引用到一个数组,或者make一个空间供切片使用。

     1. 简单切片表达式

      这种就是上面第一个例子,基于数组得到切片,常见的使用方式是  identifier[low: high] ,low和high表示一个索引范围(左包含,又不包含),有点类似于php中函数substr(),可以对slice里面的元素进行截取。

    2. make创建slice方式

      make创建slice是这样的:make([]Type, size, cap), Type表示切片的元素类型,size表示slice中元素的数量,cap表示切片的容量,可以传入前面2个参数,第3个参数可以省略。

 

 

slice截取

   通过从数组或者slice直接截取截取也是比较常见的一种创建 slice 的方法,可以通过设置下限索引的位置及上限索引的位置来截取切片。

arr := [...]int{0,1,2,3,4,5,6,7}
fmt.Println("arr[2:6] = ", arr[2:6]) 
fmt.Println("arr[:6] = ", arr[:6]) 
fmt.Println("arr[2:] = ", arr[2:]) 
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]

   第一个:[2:6] 从索引2(闭区间:包含)开始到索引6(开区间:不包含),这中间区域的值 2 3 4 5。

   第二个:[:6] 省略左索引(默认从0开始)到索引6(开区间:不包含),这段区域的值 0 1 2 3 4 5。

   第三个:[2:] 省略右索引(默认最大的索引)就是从索引2(闭区间:包含)一直到最后,这段区域的值 2 3 4 5 6 7 。

   第四个:[:] 省略左右索引,表示全部,展示所有的元素 0  1 2 3 4 5 6 7。

   

基于已有slice创建新slice,这就是reslice。

 

append()方法为切片添加元素

  Go语言的内建函数append()可以为切片动态添加元素,每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()函数调用时,所以我们通常都需要用原变量接收append函数的返回值。

func main(){
    //append()添加元素和切片扩容
    var numSlice []int
    for i := 0; i < 10; i++ {
        numSlice = append(numSlice, i)
        fmt.Printf("%v  len:%d  cap:%d  ptr:%p\n", numSlice, len(numSlice), cap(numSlice), numSlice)
    }
}

输出结果

[0]  len:1  cap:1  ptr:0xc0420080a0
[0 1]  len:2  cap:2  ptr:0xc0420080f0
[0 1 2]  len:3  cap:4  ptr:0xc04200e340
[0 1 2 3]  len:4  cap:4  ptr:0xc04200e340
[0 1 2 3 4]  len:5  cap:8  ptr:0xc04200c200
[0 1 2 3 4 5]  len:6  cap:8  ptr:0xc04200c200
[0 1 2 3 4 5 6]  len:7  cap:8  ptr:0xc04200c200
[0 1 2 3 4 5 6 7]  len:8  cap:8  ptr:0xc04200c200
[0 1 2 3 4 5 6 7 8]  len:9  cap:16  ptr:0xc042062080
[0 1 2 3 4 5 6 7 8 9]  len:10  cap:16  ptr:0xc042062080

从上面的结果可以看出:

  1. append()函数将元素追加到切片的最后并返回该切片。
  2. 切片numSlice的容量按照1,2,4,8,16这样的规则自动进行扩容,每次扩容后都是扩容前的2倍。

 

 

二. 集合(Map)

 

   Map是一种无序的键值对的集合,其内部主要使用的是hash table这种数据结构,可以通过key来快速查询数据,也可以进行增删查的操作。

map的创建

  可以使用内建函数make,也可以使用map关键字来创建Map。

    1. map关键字创建:var  mapName map[keyType]valueType  

      2. make函数创建:map[KeyType]ValueType

  

 

posted @ 2020-06-06 00:58  songguojun  阅读(506)  评论(0编辑  收藏  举报