go语言
1.切片类型
2.map的使用
3.字符串
4.指针
5.结构体
一.切片类型
切片是由数组建立的一种方便、灵活且功能强大的包装(Wrapper)。切片本身不拥有任何数据。它们只是对现有数组的引用。
练习:
1 // 切片 2 package main 3 4 import ( 5 "fmt" 6 ) 7 8 func main() { 9 // 切片定义的第一种方式,由数组切出来 10 //var a [8]int=[8]int{1,2,3,4,5,6,7,8} 11 //// 只是对数组的引用 12 //var b []int=a[2:6] 13 //fmt.Println(b) 14 //// 修改索引2的值为30 15 //a[2]=30 16 //fmt.Println(b) 17 //b[1]=40 // 这里改的是切片的值 18 //fmt.Println(b) 19 //// 底层数组的修改会影响切片 20 //// 切片的修改也会影响底层数组 21 //fmt.Println(a) 22 //a[1]=20 23 //fmt.Println(b) 24 // 更多用法,go语言是没有步长的 25 //var a [8]int=[8]int{1,2,3,4,5,6,7,8} 26 //b:=a[:4] 27 //fmt.Println(b) 28 // 第二种方式,直接定义 29 // 切片空值是?nil类型 30 //var a []int 31 //if a==nil{ 32 // fmt.Println("我是空的") 33 //} 34 //a[0]=10 这是错误的,等于说你索引个空值改值 35 //fmt.Println(a) 36 // 定义并初始化,第一个数字是切片的长度,第二个数字是底层数组长度,也就是切片的容量 37 // 切片的长度就是我切了多少值,那么容量是这个数组有多大,我切片不能超过这个数组 38 //var a []int=make([]int,3,8) 39 //fmt.Println(a) //[0 0 0] 40 // 切片的长度和容量(切片的长度用len查看 容量用cap查看) 41 //var a [8]int=[8]int{1,2,3,4,5,6,7,8} 42 //var b []int=a[2:6] 43 //fmt.Println(len(b)) // 切片长度是4 44 //fmt.Println(cap(b)) // 数组容量是6,因为前面2个被切掉了,所以是6 45 // 切片长度是3 数组容量是4 46 //var a []int=make([]int,3,4) 47 //fmt.Println(a) 48 //fmt.Println(len(a)) 49 //fmt.Println(cap(a)) 50 51 // 切片追加值 52 //var a [8]int=[8]int{1,2,3,4,5,6,7,8} 53 //var b []int=a[2:6] 54 //fmt.Println(len(b)) 55 //fmt.Println(cap(b)) 56 //// 追加值用内置函数append 如何添加值,括号填入你要给那个添加值,添加什么值 57 //b=append(b,555) 58 //b=append(b,666) 59 //fmt.Println(b) 60 //fmt.Println(len(b)) // 添加进去后切片长度变为6 61 //fmt.Println(cap(b)) // 容量还是6,没有变 62 //// 修改切片后的索引0号位的值为999 63 //b[0]=999 64 //fmt.Println(a) // [1 2 999 4 5 6 555 666] 65 //b=append(b,777) 66 //fmt.Println(b) 67 //fmt.Println(len(b)) // 长度为7,添加了一个值 68 //// 注意容量为什么变为12了,原始的容量为6,但是我添添加了三个值, 69 //// 撑破了我给设定的数组容量,只要撑破了原始的数组容量,容量就会翻倍 70 //fmt.Println(cap(b)) //容量变为12, 71 //b[0]=999 72 //fmt.Println(b) 73 //fmt.Println(a) 74 // 练习 75 //var b =make([]int,3,4) 76 //fmt.Println(b) //[0 0 0] 77 //b=append(b,4) 78 //fmt.Println(b)//[0 0 0 4] 79 //fmt.Println(len(b)) // 切片长度原始设定的是三,添加一个值,变成了4 80 //fmt.Println(cap(b)) // 数组容量是4,没有撑破 81 //b=append(b,5) 82 //fmt.Println(b) 83 //fmt.Println(len(b)) // 切片的长度变成了5 84 //fmt.Println(cap(b))// 撑破了原始的数组容量4翻倍变成了8 85 86 // 切片的修改 make就是快速生成一个切片和原始数组的容量 87 //var b =make([]int,3,4) 88 //b[0]=999 89 //fmt.Println(b) 90 //var b =make([]int,4,4) 91 //fmt.Println(len(b)) //4 92 //fmt.Println(cap(b)) //4 93 94 //切片的函数传递 95 //var b =make([]int,3,4) 96 //test(b) 97 //fmt.Println(b) 98 99 // 切片的数据结构表示 100 //type slice struct { 101 // Length int // 切片的长度 102 // Capacity int // 切片的容量 103 // ZerothElement *byte // 指向数组的指针 104 //} 105 106 // 切片的初始化 107 //var a []int=[]int{1,2,3} 108 //fmt.Println(a) 109 //fmt.Println(len(a)) 110 //fmt.Println(cap(a)) 111 112 // 多维切片 113 //var a [][]string=make([][]string,2,3) 114 //fmt.Println(a[0]) // 因为这是2个,里面还有一个没有初始化 115 //// 在初始化一下 116 //a[0]=make([]string,2,3) 117 //if a[0]==nil{ 118 // fmt.Println("xxx") 119 //} 120 121 // 多维切片初始化方法 122 //var a [][]string=[][]string{{"1","2"},{"3","4"}} 123 //fmt.Println(a) //[[1 2] [3 4]] 124 //fmt.Println(len(a)) // 2 125 //fmt.Println(cap(a)) // 2 126 //// 如果需要修改值的话,需要先索引拿到第一个数组,在索引取值 127 //a[0][1]="999" 128 //fmt.Println(a) //[[1 999] [3 4]] 129 130 // copy函数 131 var a =make([]int,3,10000) 132 a[1]=99 133 a[2]=888 134 fmt.Println(a) //[0 99 888] 135 136 //var b =make([]int,4,4) 137 var b=make([]int,2,4) 138 fmt.Println(b) //[0 0] 139 copy(b,a) // 就是前面的被后面的替换掉了 140 fmt.Println(b) 141 142 } 143 144 func test(b []int) { 145 b[0]=999 146 fmt.Println(b) 147 }
二.map的使用
map 是在 Go 中将值(value)与键(key)关联的内置类型。通过相应的键可以获取到值
在map里面类型固定是什么就是什么,不能改变
创建
var a map[键值类型]value值类型
如何初始化
// map的初始化
//var a map[int]string=make(map[int]string)
//定义和初始化的第二种方式
//var a =map[int]string{1:"10",2:"100"}
1 // map 字典 2 package main 3 4 import "fmt" 5 6 func main() { 7 // maps的定义 8 // map的key值必须可hash 9 // var a map[键值类型]value值类型 10 // map的空值是nil类型 11 //var a map[int]string 12 //fmt.Println(a) 13 //if a==nil{ 14 // fmt.Println("xxx") 15 //} 16 17 // map的赋值跟取值 18 // map的初始化 19 //var a map[int]string=make(map[int]string) 20 //fmt.Println(a) //map[] 没有添加值 是空 21 // 初始化以后就不会打印这个了,可以使用了 22 //if a==nil{ 23 // fmt.Println("xxx") 24 //} 25 //a[1]="100" 26 //a[2]="888" 27 //fmt.Println(a) //添加了2个值 map[1:100 2:888] 28 //fmt.Println(a[1]) // 取值,取索引为1的 100 29 //// 取一个不存在的key值,会返回value值的空值 30 //fmt.Println(a[9]) 31 32 //var b map[int]int=make(map[int]int) 33 //b[1]=100 34 //fmt.Println(b) //map[1:100] 35 ////fmt.Println(b[9]) // 0 36 //// 提供了这么一个来判断值存不存在 37 //// 只要判断这个ok就行了 38 //// 可以在if里面定义变量,ok有值就是true,没有值就是false了 39 //if v,ok:=a[9];ok{ 40 // fmt.Println("-------",v) 41 //}else{ 42 // fmt.Println("该值不存在") 43 //} 44 //v,ok:=a[1] 45 //fmt.Println(v) 46 //fmt.Println(ok) 47 48 //定义和初始化的第二种方式 49 //var a =map[int]string{1:"10",2:"100"} 50 //fmt.Println(a[1]) //100 51 //fmt.Println(a) //map[1:10 2:100] 52 53 // 字典删除元素,内置函数 54 //var a =map[int]string{1:"10",2:"100"} 55 //// 直接使用内置函数delete,第一个填入是你需要删除的是哪个map 56 //delete(a,2) //删除key为2的 57 //delete(a,3) // 删除没有的也没事,不会影响什么 58 //fmt.Println(a) 59 60 //map长度 61 //var a =map[int]string{1:"10",2:"100"} 62 //delete(a,1) // 删除一个还剩一个 63 //a[10] ="999" // 然后又添加了一个,还有2个 64 //fmt.Println(len(a)) 65 //// map 是引用类型 66 67 //var a =map[int]string{1:"10",2:"100"} 68 //test4(a) 69 //fmt.Println(a) 70 // Map 的相等性 71 72 //map1:=map[string]int{ 73 // "one":1, 74 // "two":2, 75 //} 76 //map2:=map1 77 //if map1 == map2{ 78 // // 比较的时候只能跟空比较,这里是报错的 79 //} 80 81 // map循环出所有元素 82 //var a =map[int]string{1:"10",0:"100",10:"999"} 83 //// map 循环不能用这种方式 84 ////for i:=0;i<len(a);i++{ 85 //// fmt.Println(a[i]) 86 ////} 87 // 88 //////map是无序的 循环的话用这种方式 89 //for k,v:=range a{ 90 // fmt.Println(k) 91 // fmt.Println(v) 92 //} 93 94 // 补充:切片删除元素 95 var a =[]int{1,2,3,4,5,6} 96 a=append(a[0:2],a[3:]...) 97 fmt.Println(a) 98 99 } 100 101 func test4(a map[int]string) { 102 a[1]="888" 103 fmt.Println(a) 104 105 }
三.字符串
// 字符串 package main func main() { //name :="Hello World刘清正" //name:="刘" // 字符串长度,len统计字节数 // 在go语言中string类型都是utf-8编码 //fmt.Println(len(name)) //20 字母和空格用一个字节表示,中文用3个字节表示 // len出来的是字节数,如果想真正统计有多少个字符用下面这个方法 //fmt.Println(utf8.RuneCountInString(name)) // unicode是一个字符编码对照表 // 循环 // 字符串是一个只读切片 //name:="name刘" // 这种循环拿出来的是一个个字节, 我想拿出来一个个字符 //for i:=0;i<len(name);i++{ // fmt.Println(string(name[i])) // // 打印类型 // fmt.Println("%T",name[i]) //} // 循环拿到一个个字符 //for _,v:=range name{ // fmt.Println(string(v)) // fmt.Printf("%T",v) // int32类型 // fmt.Println() //} //name :="name刘" ////name[0]=99 字符串是不能改值的 ////fmt.Println(name[0]) //fmt.Println(string(name[0])) //n //fmt.Println(string(name)) //name刘 }
四.指针
指针是一种存储内存地址(Memory Address)的变量
// & 取地址符号 // // * 放在类型旁边,表示指向这个类型的指针 // // * 放在变量旁边,表示解引用(反解) // //a:=10 // //fmt.Println(&a) // 取到的是一个地址 0xc00000a0c8 // // b就是一个指针,指向int类型的指针 我指向的是什么类型,就在这个类型前面加星号 // //b:=&a // 取了a的地址赋值给变量b // //var b *int = &a // b存储了a的内存地址,如何通过b拿到10 // //fmt.Println(b) // 打印的是a的地址 0xc00000a0c8 // //fmt.Println(*b) // 只要在b前面加上一个*号就可以了,反解 // // 这个要是想拿到10需要解2层,*int本来就是指向类型再星就是指向上面的*int // // 可以一直赋值变量,无线叠加 // //var c **int=&b // //fmt.Println(*(*c))
1 // 指针 2 package main 3 4 import "fmt" 5 6 func main() { 7 // & 取地址符号 8 // // * 放在类型旁边,表示指向这个类型的指针 9 // // * 放在变量旁边,表示解引用(反解) 10 // //a:=10 11 // //fmt.Println(&a) // 取到的是一个地址 0xc00000a0c8 12 // // b就是一个指针,指向int类型的指针 我指向的是什么类型,就在这个类型前面加星号 13 // //b:=&a // 取了a的地址赋值给变量b 14 // //var b *int = &a // b存储了a的内存地址,如何通过b拿到10 15 // //fmt.Println(b) // 打印的是a的地址 0xc00000a0c8 16 // //fmt.Println(*b) // 只要在b前面加上一个*号就可以了,反解 17 // // 这个要是想拿到10需要解2层,*int本来就是指向类型再星就是指向上面的*int 18 // // 可以一直赋值变量,无线叠加 19 // //var c **int=&b 20 // //fmt.Println(*(*c)) 21 22 // 指针的零值,就是nil类型 23 //var a *int 24 //fmt.Println(a) 25 26 //向函数传递指针参数 27 //a:=10 28 ////b:=&a 29 ////test6(b) 30 ////fmt.Println(a) 31 //test7(a) 32 //fmt.Println(a) 33 34 // 建议:不要向函数传递数组的指针,而应该使用切片 35 //var a [100]int 36 // 在函数里面修改数组 37 ////test9(&a) 38 ////fmt.Println(a) 39 //test10(a[:]) 40 //fmt.Println(a) 41 //Go 不支持指针运算 42 43 44 } 45 // 取地址修改才可以修改原来的 46 func test9(a *[4]int) { 47 (*a)[0]=999 48 fmt.Println(a) 49 } 50 // 这样不会修改原来的 51 func test10(a []int) { 52 a[0]=999 53 fmt.Println(a) 54 55 } 56 //func test6(b *int) { 57 // 我想把a的值改掉 打印就是11 这个是根据地址改的,所以都改掉了 58 // //*b 就是 a a++ 59 // *b++ 60 // fmt.Println(*b) 61 //} 62 //func test7(b int) { 63 // 但是如果这么写 直接改b只有一个改了,只有改地址了,才是改原来的 64 // b++ 65 // fmt.Println(b) 66 // 67 //}
五.结构体
什么是结构体:
结构体是用户定义的类型,表示若干个字段(Field)的集合。有时应该把数据整合在一起,而不是让这些数据没有联系。这种情况下可以使用结构体。
例如,一个职员有 firstName、lastName 和 age 三个属性,而把这些属性组合在一个结构体 employee 中就很合理。
定义初始化:
//var person Person=Person{name:"lqz",age:18,sex:1}
//p:Person{name:"lqz"} 这种方法比较常用