Go切片、Map、数组、列表

1 切片
A 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用传递的机制
B 切片的使用和数组类似,遍历切片、访问切片的元素和求切片长度len(slice)都一样
C 切片的长度是可以变化的,因此切片是一个可以动态变化的数组
func main() {
var arr = [...]string{"张学友","刘德华","黎明","郭富城","成龙","周星驰"}
slice :=arr[1:3:5]
fmt.Printf("slice容量:%d, 长度:%d,值:%v\n",cap(slice),len(slice),slice)
fmt.Printf("slice地址:%p",slice)
fmt.Printf("slice的类型:%T",slice) //[]string
fmt.Printf("array的类型:%T",arr) //array
}
slice容量:4, 长度:2,值:[刘德华 黎明]
slice地址:0xc420054070
slice的类型:[]string
array的类型:[6]string
2 切片的特征
a 切片是以个引用类型
b slice的底层是以个数据结构 (struct结构体)
3 切片定义
A var sliceName [] type
举栗: var a [] int 整型的切片
B
var sliceName [] type = make([]type,len,[cap])
举栗: var slice = make([]int,3,5)
type: 就是数据类型
len : 大小
cap :指定切片容量,可选, 如果你分配了 cap,则要求 cap>=len
通过 make 方式创建切片可以指定切片的大小和容量
如果没有给切片的各个元素赋值,那么就会使用默认值[int , float=> 0 string =>”” bool =>false]
通过 make 方式创建的切片对应的数组是由 make 底层维护,对外不可见,即只能通过 slice 去访问各个元素
C 直接就指定具体数组
slice :=[]string{"张学友","刘德华","黎明","郭富城","成龙","周星驰"}
数组的定义
  • var arrayName [size] arrayType
4 切片的遍历
A
for i:=0; i<len(slice) ; i++ { fmt.Printf("%d ===> %v\n",i,slice[i]) }
B
or index,value := range slice{ fmt.Printf("%d ===> %v\n",index,value) }
5 切片的清空
  1. a := []int{1, 2, 3}
  2. fmt.Println(a[0:0]) //[]
6 append() 和copy() 函数
var numbers [] int
向切片添加一个元素
 numbers = append(numbers, 1)
//把numbers拷贝到number1
copy(number1,numbers)
二 map
map是key-value数据结构,又称为字段或者关联数组,类似其他编程语言的集合
A 声明
var variableName map[keyType] valueType
keyType不可以是slice,map,func
var Jack map[string] string
声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用
分配内存要用make
func make(Type, size IntegerType) Type
内建函数make分配并初始化一个类型为切片、映射通道的对象,其第一个实参为类型,而非值。make的返回类型与其参数相同,而非指向它的指针。其具体结果取决于具体的类型:
切片:size指定了其长度,该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量;它必须不小于其长度,因此make([]int,0,10) 会分配一个长度为0,容量为10的切片
map:初始分配的创先取决于size,但产生的映射长度为0.size可以省略,这种情况下就会分配一个小的起始大小
channel: 通道的缓存根据指定的缓存容量初始化。若size为零或被省略,该通道即为无缓存的。
B map的操作
a 增加和更新
map["key"] = value
b map删除
delete(map,"key")
delete 是一个内置函数,如果 key 存在,就删除该 key-value,如果 key 不存在,
不操作,但是也不会报错
删除整个map
b1 遍历删除
b2 map = make(...) make 一个新的,让原来的成为垃圾,被 gc 回收
c map的查找
value:=map[key]
make 一个新的,让原来的成为垃圾,被 gc 回收
d map的遍历
for key,value:= range m{ fmt.Printf("key:%v ; value:%v\n",key,value) }
总结:
  1. map 在使用前一定要 make
  2. map 的 key 是不能重复,如果重复了,则以最后这个 key-value 为准
  3. map 的 value 是可以相同的.
  4. map 的 key-value 是无序
  5. map 的容量达到后,再想 map 增加元素,会自动扩容,并不会发生 panic,也就是说 map 能动态的增长 键值对(key-value)
  6. map 的 value 也经常使用 struct 类型,更适合管理复杂的数据(比前面 value 是一个 map 更好),比如 value 为 Student 结构体
三 数组
数组
数组是具有相同唯一类型的一组编号且长度固定的数据项序列
数组只能存放相同类型的变量,并且长度不能动态变长
数组的传值属性是值传递
数组的边界不能超出指定长度否则会报越界错误
在变量传递的过程中如果传递的数组[3]int 接收只能是[3]int
声明数组
直接声明:var arr [3]int
make声明 arr:=make([]int,3)
字面量:a := [2]int{1, 2}
自动识别长度 :b := [...]int{1, 2}
二维数组:arr:[4][4]int{{1},{1,2},{1,2,3}}
new: arrp := new([10]int)
遍历数组
for k,v:=range a{
}
for i:= 0;i<len(a);i++{
fmt.Print(a[i],"\t")
}
数组的长度 len(arr)
数组排序
引入sort包 import "sort"
升序
整型排序 sort.Ints(arrayInt)
浮点型排序 sort.Floats64s(arrayFloat)
字符串型排序 sort.Strings(arrayString)
降序
sort.Sort(sort.Reverse(sort.IntSlice(arrayInt)))
sort.Sort(sort.Reverse(sort.Float64Slice(arrayFloat)))
sort.Sort(sort.Reverse(sort.StringSlice(arrayString)))
指针数组: 指针数组是一个存储指针的集合
a:=1
b:=2
pscore2 := [...]&int{&a, &b}
指向数组的指针:是指一个指针指向某个数组
var pscore *[5]int = &score3
多维数组
所以多维数组的所有维度都会在创建时自动初始化零值,多维数组尤其适合管理具有父子关系或者与坐标系相关联的数据。
var array_name [size1][size2]...[sizen] array_type
其中,array_name 为数组的名字,array_type 为数组的类型,size1、size2 等等为数组每一维度的长度。
  1. / 声明一个二维整型数组,两个维度的长度分别是 4 和 2
  2. var array [4][2]int
四 列表
列表是一种非连续的存储容器,由多个节点组成,节点通过一些变量记录彼此之间的关系,列表有多种实现方法,如单链表、双链表等。
在Go语言中,列表使用 container/list 包来实现,内部的实现原理是双链表,列表能够高效地进行任意位置的元素插入和删除操作。
初始化列表
1) 通过 container/list 包的 New() 函数初始化 list
变量名 := list.New()
2) 通过 var 关键字声明初始化 list
var 变量名 list.List
列表与切片和 map 不同的是,列表并没有具体元素类型的限制,因此,列表的元素可以是任意类型,这既带来了便利,也引来一些问题,例如给列表中放入了一个 interface{} 类型的值,取出值后,如果要将 interface{} 转换为其他类型将会发生宕机
在列表中插入元素
双链表支持从队列前方或后方插入元素,分别对应的方法是 PushFront 和 PushBack。
这两个方法都会返回一个 *list.Element 结构,如果在以后的使用中需要删除插入的元素,则只能通过 *list.Element 配合 Remove() 方法进行删除,这种方法可以让删除更加效率化,同时也是双链表特性之一。
下面代码展示如何给 list 添加元素:
  1. l := list.New() //创建一个列表实例
  2. l.PushBack("fist") // 将 fist 字符串插入到列表的尾部,此时列表是空的,插入后只有一个元素。
  3. l.PushFront(67) //将数值 67 放入列表,此时,列表中已经存在 fist 元素,67 这个元素将被放在 fist 的前面。
列表插入元素的方法如下表所示。
方  法
功  能
InsertAfter(v interface {}, mark * Element) * Element
在 mark 点之后插入元素,mark 点由其他插入函数提供
InsertBefore(v interface {}, mark * Element) *Element
在 mark 点之前插入元素,mark 点由其他插入函数提供
PushBackList(other *List)
添加 other 列表元素到尾部
PushFrontList(other *List)
添加 other 列表元素到头部
遍历列表
  1. l := list.New()
  2. // 尾部添加
  3. l.PushBack("canon")
  4. // 头部添加
  5. l.PushFront(67)
  6. for i := l.Front(); i != nil; i = i.Next() {
  7. fmt.Println(i.Value)
  8. }

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注