一、goto
* goto是Go语言中的一个关键字
* goto让编译器执行时跳转到特定位置
* Loop是标记名(Label),名称任意,习惯上名称为Loop
fmt.Println("执行程序")
i := 6
if i == 6 {
goto Loop
}
fmt.Println("if下面输出")
Loop:
fmt.Println("loop")
* 可以有多个,但是标签(Labal)定义了就必须使用
二、切片
* 切片的英文名称slice
* 切片是具有可变长度的相同类型的元素序列.
* 由于长度是可变的可以解决数组长度在数据个数不确定情况下浪费内存的问题.
* 切片和数组声明时语法最主要的区别就是长度
var slice []string //切片
var array [3]string //数组
* 切片只声明时为nil,没有开辟内存空间,不能直接操作切片,需要先初始化
* 注意:切片只能和nil进行判断是否相等
* 通过直接指定初始值定初始化一个切片变量
* 定义完切片后就可以通过切片对象[脚标]取出或修改切片中元素内容.语法和数组相同
* 引用类型在变量之间赋值时传递的是地址.引用类型变量就是这个类型的指针.切片就是引用类型
* 值类型在变量之间赋值时传递的是值的副本
三、make函数
* Go语言中可以使用make函数创建slice 、 map、 channel、 interface
* 使用make函数定义无内容,但是不是nil的切片,意味着切片已经申请了内存空间
* make(类型,初始长度[,初始容量])
* 初始容量可以省略,默认和长度相等
slice := make([]string, 0) //长度为0的切片,没有第三个参数表示容量和长度相等
* 长度表示切片中元素的实际个数,容量表示切片占用空间大小,且切片容量成倍增加.当增加到1024后按照一定百分比增加.
* len(slice) 查看切片的长度
* cap(slice) 查看切片的容量
四、append()函数
* 可以向切片中添加一个或多个值,添加后必须使用切片接收append()函数返回值
s := make([]string, 0)
fmt.Println(len(s), cap(s))//输出:0 0
s = append(s, "老张", "佳明哥")
fmt.Println(len(s), cap(s))//输出:2 2
s = append(s, "smallming")
fmt.Println(len(s), cap(s))//输出:3 4
* 如果一次添加多个值,且添加后的长度大于扩容一次的大小,容量和长度相等。等到下次添加内容时如果不超出扩容大小,在现在的基础上进行翻倍
* 也可以把一个切片的内容直接添加到另一个切片中.需要注意语法中有三个点
s := make([]string, 0)
s1 := []string{"smallming", "佳明哥"}
s = append(s, s1...) //注意此处,必须有三个点
fmt.Println(s)
五、通过数组产生切片
* 定义数组后,取出数组中一个片段,这个片段就是切片类型
names := [3]string{"老张", "佳明哥", "smallming"}
s := names[0:2] //包前不包后
fmt.Printf("%T", s) //输出:[]string
fmt.Println(s) //输出:[老张 佳明哥]
* 切片是指针,指向数组元素地址,修改切片的内容,数组的内容会跟随变化
* 当切片内容在增加时
* 如果增加后切片的长度没有超出数组,修改切片也是在修改数组
* 如果增加后切片的长度超出数组,会重新开辟一块空间放切片的内容
* Go语言标准库中没有提供删除的函数
* 切片也可以取其中的一段形成子切片,利用这个特性可以实现删除效果
六、copy函数
* 通过copy函数可以把一个切片内容复制到另一个切片中
* Go语言标准库源码定义如下
* 第一个参数是目标切片,接收第二个参数内容
* 第二个参数是源切片,把内容拷贝到第一个参数中
* 拷贝时严格按照脚标进行拷贝.且不会对目标切片进行扩容
* 把短切片拷贝到长切片中
s1:=[]int {1,2}
s2:=[]int {3,4,5,6}
copy(s2,s1)
fmt.Println(s1)//输出:[1 2]
fmt.Println(s2)//输出:[1 2 5 6]
* 把长切片拷贝到短切片中
s1:=[]int {1,2}
s2:=[]int {3,4,5,6}
copy(s1,s2)
fmt.Println(s1)//输出:[3 4]
fmt.Println(s2)//输出:[3 4 5 6]
* 使用copy完成删除元素
七、sort包
* Go语言标准库中sort提供了排序API
* sort包提供了多种排序算法,这些算法是内部实现的,每次使用sort包排序时,会自动选择最优算法实现
* 插入排序
* 快速排序
* 堆排
* sort包中最上层是一个名称为Interface的接口,只要满足sort.Interface类型都可以排序
* Go语言标准库默认提供了对int、float64、string进行排序的API
* 很多函数的参数都是sort包下的类型,需要进行转换.
* 对int类型切片排序
num := [] int{1, 7, 5, 2, 6}
sort.Ints(num) //升序
fmt.Println(num)
sort.Sort(sort.Reverse(sort.IntSlice(num))) //降序
fmt.Println(num)
* 对float64类型切片排序
f := [] float64{1.5, 7.2, 5.8, 2.3, 6.9}
sort.Float64s(f) //升序
fmt.Println(f)
sort.Sort(sort.Reverse(sort.Float64Slice(f))) //降序
fmt.Println(f)
* 对string类型切片排序
* 按照编码表数值进行排序
* 多字符串中按照第一个字符进行比较
* 如果第一个字符相同,比较第二个字符
八、map
* map以散列表方式存储键值对集合
* map中每个元素都是键值对
* map[key]Value
* key是操作map的唯一标准.可以通过key对map中元素进行增加/删除/修改/查看
* key是唯一的,添加重复的key会覆盖之前的元素.
* map是值类型,只声明时为空指针(nil)
* 使用make函数实例化一个没有初始值的map
m := make(map[string]string)
* 可以在声明map时直接给map赋初始值.注意初始值在一行和在多行写时的语法区别
* map中元素键值对语法满足: key:value
* key和value的类型必须和map[key]value类型严格对应
m := map[string]string{"name": "smallming", "address": "北京海淀"}
m1 := map[string]string{
"name": "smallming",
"addresss": "北京海淀",
}
* 使用key判断,如果key不存在就向map中新增数据,如果key存在会覆盖map中元素
m := make(map[string]int)
m["money"] = 5
fmt.Println(m) //输出:map[money:5]
m["money"] = 6
fmt.Println(m) //map[money:6]
* Go语言标准库中提供了对map元素删除的函数,使用顶层delete()即可完成删除
* 如果key存在执行删除元素
* 如果key不存在,map中内容不变,也不会有错误
m := make(map[string]int)
m["money"] = 5
delete(m, "没有的key")
fmt.Println(m) //输出:map[money:5]
delete(m, "money")
fmt.Println(m) //输出:map[]
* 获取map中指定key对应的值
* 使用:map变量[key]获取key对应的值
* 如果key不存在返回map[key]Value中Value类型的默认值.例如:Value是string类型就返回""
* 返回值可以是一个,也可以是两个.
* 一个表示key对应的值
* 两个分别表示:key对应的值和这个key是否存在
m := map[string]string{"name": "smallming", "address": "北京海淀"}
fmt.Println(m["name"]) //输出:smallming
fmt.Println(m["age"]) //输出:空字符串
value, ok := m["age"]
fmt.Println(value, ok) //输出:空字符串 false
* 如果希望把map中所有元素都遍历,可以使用for结合range实现
m := map[string]string{"name": "smallming", "address": "北京海淀"}
//range遍历map时返回值分别表示key和value
for key, value := range m {
fmt.Println(key, value)
}