一、指针
区别于C/C++中的指针,Go语言中的指针不能进行偏移和运算,是安全指针。
- &: 取地址
- *: 根据地址取值
func zz() {
var p = "zerp"
fmt.Println(&p) //0xc00003c1f0
c := &p
*c = "test"
fmt.Println(c, *c, p) //0xc00003c1f0 test test
num := 9
sum(&num)
fmt.Println(num)
}
func sum(a *int) {
*a = *a + 10
}
当一个指针被定义后没有分配到任何变量时,它的值为 nil
var a *int //声明指针变量
fmt.Println(a) //没有分配任何变量 只为 nil
b := 20
a = &b // 指针变量的存储地址
fmt.Println(&a, a, *a)//0xc000006030 0xc0000120a8 20
二、流程控制
- 如果:if-else
if a := 1; a < 2 {
fmt.Println(a) // 1
}
- 选择:Switch
a := 5
switch a {
case 0:
fmt.Println(0)
fallthrough //可继续向下执行 默认不往下执行
case 1:
fmt.Println(1)
case 2:
fmt.Println(2)
case 3, 4, 5:
fmt.Println(a)
}
//不用传比较值直接写条件
switch {
case a > 4:
fmt.Println("> 1 :", a)
}
- 循环:for
// 1 输出 1 2 3
c := 1
for {
fmt.Println(c)
if c == 3 {//不加条件则死循环
break
}
c++
}
// 常规写法
for a := 0; a < 2; a++ {
fmt.Println(a)
}
// 带入条件判断是否进入for
b := 3
for b == 1 {//满足条件则进入for
fmt.Println(b)
b++
}
-
结束与跳过:break - continue
-
跳转:goto
三、数组
全局
var arr0 [5][3]int
var arr1 [2][3]int = […][3]int{{1, 2, 3}, {7, 8, 9}}
局部:
a := [2][3]int{{1, 2, 3}, {4, 5, 6}}
b := […][2]int{{1, 1}, {2, 2}, {3, 3}} // 第 2 纬度不能用 “…”。
/***** 一维数组 *****/
//设置固定长度 5
var arr1 [5]int = [5]int{1, 2, 3, 4, 5}
fmt.Println(arr1) //[1 2 3 4 5]
// [...] 设置变长
var arr2 = [...]int{1, 2, 3}
fmt.Println(arr2) //[1 2 3]
/*** 二维数组 ***/
arr3 := [2][2]int{{1, 2}, {2, 3}}
fmt.Println(arr3) //[[1 2] [2 3]]
//len -- 来求长度,比如string、array、slice、map、channel ,返回长度
fmt.Println(len(arr3))//2
四、切片
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大
- 特点
- 切片:切片是数组的一个引用,因此切片是引用类型。但自身是结构体,值拷贝传递。
- 切片的长度可以改变,因此,切片是一个可变的数组。
- 切片遍历方式和数组一样,可以用len()求长度。表示可用元素数量,读写操作不能超过该限制。
- cap可以求出slice最大扩张容量,不能超出数组限制。0 <= len(slice) <= len(array),其中array是slice引用的数组。
- 切片的定义:var 变量名 []类型,比如 var str []string var arr []int。
- 如果 slice == nil,那么 len、cap 结果都等于 0。
- 定义
- var slice1 []type = make([]type, len,cap) 或 slice1 := make([]type, len,cap)
- var arr1 []int = []int{0, 2} 或 arr1 := []int{0, 2}
///ar arr1 []int = []int{0, 2} 或 arr1 := []int{0, 2}
var sar []int = []int{1, 2, 3, 5}
fmt.Println(sar) //[1 2 3 5]
fmt.Println(sar[1:2])//输出[2] 从下标1开始 2之前结束
fmt.Println(sar[1:], cap(sar[1:])) //输出[2,3,5] 3 从下标1开始结束 ,容量会重新计算
fmt.Println(sar[:3], cap(sar[:3])) //输出[1,2,3] 4 从开始 3之前结束 , 从开始获取值cap会继承原数组容量
fmt.Println(len(sar))//长度 4
fmt.Println(cap(sar))//容量 4
sar = append(sar, 10)
fmt.Println(sar) //[1 2 3 5 10]
fmt.Println(len(sar))//5
fmt.Println(cap(sar))//8 数组增加元素时容量扩容 小于1024长度时倍增,大于1024时增长为 1/4
//var slice1 []type = make([]type, len,cap) 或 slice1 := make([]type, len,cap)
sar := make([]int, 0)
fmt.Println(sar, len(sar), cap(sar))// [] 0 0
sar1 := make([]int, 1, 10)
fmt.Println(sar1, len(sar1), cap(sar1))//[0] 1 10
sar2 := make([]int, 5)
fmt.Println(sar2, len(sar2), cap(sar2))//[0 0 0 0 0] 5 5
五、Map集合
// 定义map集合
var goClassMap map[string]string
goClassMap = make(map[string]string)
// 或
// goClassMap := make(map[string]string)
// 添加数据
goClassMap[“teacher”] = “shineyork”
goClassMap[“contents”] = “go”
fmt.Println(goClassMap)
maps := make(map[string]string, 0)
maps["key"] = "val"
maps["key2"] = "val2"
fmt.Println(maps) //map[key:val key2:val2]
//值类型时切片
smap := make(map[string][]string, 0)
s := make([]string, 0)
s = append(s, "a", "b")
smap["key"] = s
fmt.Println(smap) //map[key:[a b]]
//切片为原型(key),value是map
smap1 := make([]map[string]string, 2)
smap1[0] = maps
smap1[1] = make(map[string]string, 0)
smap1[1]["name"] = "zero"
smap1[1]["age"] = "18"
fmt.Println(smap1) //[map[key:val key2:val2] map[age:18 name:zero]]
//foreach 遍历循环
for key, val := range smap1 {
fmt.Println(key, val) //0 map[key:val key2:val2] 1 map[age:18 name:zero]
}