第二章 Go语言数据类型

红太狼 2023-06-02 13:56 99阅读 0赞

一、整数类型

  按照长度分为:    int8 、int16 、int32 、int64

  对应的无符号整型:  uint8、uint16、uint32、uint64

  获取对象的长度用len()

  进制

    十进制:

        var a int = 10

        fmt.Printf(“%d \n”,a)  //10

        fmt.Printf(“%b \n”,a)  //1010 占位符%b表示二进制

    八进制:

        var b int = 077

        fmt,Printf(“%o \n”,c)  //ff

    十六进制:

        var c int = oxff

        fmt.Printf(“%x \n”,c)  //ff

        fmt.Printf(“%X \n”,c)  //FF

  内存地址:

    fmt.Printf(“%p \n”,&a)  //0x00004c080  占位符%p表示十六进制的内存地址

  注:不同int类型之间不能转换相加减,需要转换成相同类型

  interface可以转换任意类型

  1. func test() {
  2. var a interface{} //{}表示空的interface
  3. var b int = 100
  4. var c float32 = 1.2
  5. var d string = "hello"
  6. a = b
  7. fmt.Println("a=", a) //100
  8. a = c
  9. fmt.Println("a=", a) //1.2
  10. a = d
  11. fmt.Println("a=", a) //hello
  12. }

二、浮点型

  类型:float32和float64  不定义默认是0  浮点数不够精确,可以把浮点数先*100或*1000编程整数进行运算  占位符输出%f

三、布尔类型

  类型:True和Flase  默认Flase  go语言不能将整型强制转换成布尔型  布尔型无法参与数值运算,也无法与其他类型转换  用%t表示格式化

四、String类型

  定义:以原生数据类型出现内部实现使用utf-8

  表示字符串:

      “ ”  //双引号输出会出现转义符的意义

      ··  //反引号会忽视转义符的意义

  字符串常用转义符:

      \r:回车符(返回行首)  \n:换行符(直接跳到下一行的同列位置)  \t:制表符  \‘:单引号  \“:双引号  \:反斜杠

  字符串常用方法

  1. +或fmt.Sprintf //拼接字符串
  2. (1)
  3. c = c+c
  4. fmt.Printf("c = %s\n",c)
  5. (2)
  6. c = fmt.Sprintf("%s%s",c,c)
  7. fmt.Printf("c=%s\n",c)
  8. strings.Split //分割
  9. import "strings"
  10. func test(){
  11. ip := "10.10.10.1;192.168.1.1"
  12. ipArray := strings.Split(ip,";")
  13. fmt.Printf("first ip :%s\n",ipArray[0])
  14. fmt.Printf("second ip :%s\n",ipArray[1])
  15. }
  16. strings.contains //判断是否包含
  17. import "strings"
  18. func test(){
  19. ip := "10.10.10.1;192.168.1.1"
  20. result := strings.Contains(ip,"10.10.10.1")
  21. fmt.Println(result) //返回布尔值
  22. }
  23. strings.HasPrefix/HasSuffix //判断前缀和后缀
  24. import "strings"
  25. func test(){
  26. str := "https://www.baidu.com"
  27. if strings.HasPrefix(str,"http"){
  28. fmt.Println("str is http url")
  29. }else{
  30. fmt.Println("str is not http url")
  31. }
  32. var last bool
  33. last = strings.HasSuffix(str,"com")
  34. fmt.Printf(last) //返回bool
  35. }
  36. strings.Index()/LastIndex() //子串出现的位置
  37. import "strings"
  38. func test(){
  39. str := "https://www.baidu.com"
  40. index := strings.Index(str,"baidu") //baidu第一次出现的位置
  41. fmt.Printf("str is index:%d\n",index)
  42. index = strings.LastIndex(str,"baidu") //baidu最后一次出现的位置
  43. fmt.Printf("baidu last index:%d\n",index)
  44. }
  45. strings.Join(a[]string,sep string) //join操作,把一个数组每一个元素根据分隔符为基准重新组成字符串
  46. func test(){
  47. var strArr []string = []string{"10.10.10.1","11.11.11.2","12.12.12.3"}
  48. resultStr = strings.Join(strArr,";")
  49. fmt.Printf("result=%s\n"mresultStr) //输出result=10.10.10.1;11.11.11.2;12.12.12.3
  50. }

五、字符类型

  定义:组成字符串的元素叫做字符,字符用’ ‘表示,分别有uint8(byte)类型,代表一个ASCII码的字符;rune类型,代表一个UTF-8字符

  1. package main
  2. import "fmt"
  3. func main(){
  4. s1 := "Golang"
  5. c1 := 'G'
  6. fmt.Println(s1,c1) //Golang 71 字符的编码
  7. s2 := "中国"
  8. c2 := '中' //汉字表示3位
  9. fmt.Println(s2,c2) //中国 20013
  10. s3 := "Go语言"
  11. fmt.Println(len(s3)) //11 一个字符1字节,中文3字节
  12. for i := 0;i<len(s3);i++{ //bytes中文乱码
  13. fmt.Printf("%c\n",s3[i]) //%c打印字符
  14. }
  15. for k,v := range s3{ //可打印中文字符
  16. fmt.Printf("%d,%c\n",v) //k表示字节的索引数
  17. }
  18. }

  强制转换字符串和utf-8

  1. func main(){
  2. s1 := "big"
  3. bytes1 := []byte(s1) //将字符串强制转换成字节数组类型
  4. fmt.Println(bytes1) //[98 105 103]分别对应了各自的字符
  5. bytes1[0] = 'p'
  6. fmt.Println(string(bytes1)) //[112 105 103]
  7. s1 = string(bytes1) //将字节数组强制转换成字符串类型
  8. fmt.Println(s1)
  9. s2 := "大白菜"
  10. runes2 := []rune(s2)
  11. runes2[0] ='小'
  12. fmt.Println(string(runes2),len(runes2))
  13. }
  14. //只有强制类型转换,不能重新赋值

  字符串反转操作

  1. //英文
  2. func main(){
  3. s1 := "hello"
  4. byteArray := []byte(s1) //[h e l l o]
  5. //方法1
  6. s2 := ""
  7. for i :=len(byteArray)-1;i>=0;i--{
  8. s2 = s2 + string(byteArray[i]) //byteArray[i] --> o l l e h
  9. }
  10. fmt.Println(s2)
  11. //方法2
  12. for i := 0;i<len(byteArray)/2;i++{
  13. byteArray[i],byteArray(len(byteArray)-1-i) = byteArray(length-1-i),byteArray[i]
  14. }
  15.   fmt.Println(string(byteArray))
  16. }
  17. //中文
  18. func main(){
  19. str := "中文"
  20. r []rune := []rune(str)
  21. for i := 0;i<len(r)/2;i++{
  22. tmp := r[len(str)-i-1]
  23. r[len(str)-i-1] = r[i]
  24. r[i] = tmp
  25. }
  26. fmt.Println(string(r[i]))
  27. }

六、指针

  变量和内存地址:每个变量都有内存地址,通过变量来操作对应大小的内存;普通变量存储的是对应类型的值,这些类型就叫做值类型

  1. func main(){
  2. var a int32
  3. a = 100
  4. fmt.Printf("the addr of a:%p",&a) //the addr of a:0x000062058
  5. }

  指针类型:指针类型的变量存储的是一个地址,所以又叫指针类型或引用类型;操作指针变量指向地址里的值

  1. func test(){
  2. var a int32
  3. a = 156
  4. fmt.Printf("the addr of b:%p,b:%v\n",&b,b)
  5. if b == nil{
  6. fmt.Println("这个指针变量为空")
  7. }
  8. b = &a //将a变量地址传到b中
  9. fmt.Printf("the addr of b:%p,b:%v\n",&b,b) //b的内容为a的地址,但b的内存地址与a不同
  10. }
  11. func test2(){
  12. var a int = 200
  13. var b *int = &a
  14. fmt.Printf("b指向的地址存储的值为:%d\n",*b) //打印b中存储的内存地址所存的数值
  15. *b = 1000 //修改b存的内存地址所存得数值
  16. fmt.Printf("b指向的地址存储的值为:%d\n",*b)
  17. fmt.Printf("a=%d\n",a)
  18. }

  指针传参

  1. func modify(a *int){
  2. *a = 100
  3. }
  4. func testvariable(){
  5. var b int = 10
  6. p := &b
  7. modify(p)
  8. fmt.Printf("b:%d\n",b) //b:100
  9. }
  10. //在p定义一个指针变量,把p传入modify中a会拷贝一份b的内存地址在自己的值中,a就可以操作b的值
  11. //数组
  12. func modify(a *[3]int){
  13. (*a)[0] = 100
  14. }
  15. func testvariable(){
  16. var b [3]int = [3]int{1,2,3}
  17. modify(&b)
  18. fmt.Println(b) //[100,2,3]
  19. }

  make和new的区别:

    make用来分配引用类型的内存,比如map,slice以及channel

    new用来分配除引用类型的所有其他类型的内存,比如int和数组

  1. func testvariable(){
  2. var a *int = new(int)
  3. *a = 100
  4. fmt.Printf("*a=%d\n",*a) //整型可以直接操作
  5. var b *[]int = new([]int)
  6. fmt.Printf("*b = %v\n",*b)
  7. (*b) = make([]int,5,10) //切片只有make后才能进行操作,否则报错
  8. (*b)[0] = 100
  9. (*b)[1] = 200
  10. fmt.Printf("*b = %v\n",*b)
  11. }

  值拷贝和引用拷贝

  1. //值拷贝
  2. func modify(){
  3. a = 100
  4. }
  5. func testvariable(){
  6. var b int = 10
  7. modify(b)
  8. fmt.Printf(*b=%d\n",b)
  9. } //b的值不变,调用modify函数是会把值拷贝过去一份,但是内存地址不一样
  10. //引用拷贝
  11. func testvariable(){
  12. var a int = 10
  13. var b *int = &a
  14. var c *int = b
  15. *c = 200
  16. fmt.Printf("*c=%d *b=%d a=%d\n",*c,*b,a)
  17. } //a的内存地址都拷贝到b和c中,所以一个操作都会修改

七、Array数组

  定义:表示同一种数据类型的集合,数组长度从声明的时候就确定了,使用时可以修改数组成员,但是数组大小不可变化

    var a [3] int  //定义一个数组,数组下标从0开始,因此长度为n的数组下标范围:[0,n-1];

    整数数组中的元素默认初始化为0,字符串数组中的元素默认初始化为””

  数组初始化:不同数组的长度和类型不同,则不能直接赋值

  1. func test(){
  2. a := [3]int{1,2,3}
  3. b := [5]int
  4. b = a //不成立
  5. }
  6. func test2(){
  7. var a [3] int //定义一个长度为3的int型数组
  8. a[0] = 10 //分别给数组中的位置传值
  9. a[1] = 20
  10. a[2] = 30
  11. //方法2
  12. var a [3]int = [3]int{10,20,30}
  13. //方法3
  14. a := [3]int{10,20,30}
  15. //方法4
  16. a := [...]int{10,20,30} //...表示任意长度,由传入的参数决定
  17. //方法5
  18. a := [3]int{10} //10,0,0
  19. //方法6
  20. a := [3]int{2:10} //索引为2的元素初始值换成10

  数组遍历

  1. func testArray(){
  2. a := [5]int{3:100,4:300}
  3. for i:=0;i<len(a);i++{
  4. fmt.Printf("a[%d]=%d\n",i,a[i]) //打印索引位和该索引位的数值
  5. }
  6. }
  7. func testArray(){
  8. a := [3]int{1,2,3}
  9. for index,value := range a{ //range会返回两个数,第一个为range的下标,第二个是值
  10. fmt.Printf("a[%d]=%d\n",index,value) //当不需要index时可以用_代替
  11. }
  12. }

  二维数组

  1. func testArray(){
  2. var a [3][2]int
  3. a[0][0] = 10
  4. a[0][1] = 20
  5. a[1][0] = 30
  6. a[1][1] = 40
  7. a[2][0] = 50
  8. a[2][1] = 60
  9. fmt.Println(a) //[[10 20] [30 40] [50 60]]
  10. for i :=0;i<3;i++{
  11. for j:=;j<2;j++{
  12. fmt.Printf("%d",a[i][j] //10 20 30 40 50 60
  13. }
  14. for i,val1 := range a{
  15. for k,val2 :=range bal1{
  16. fmt.Printf("(%d,%d)=%d",i,j,val2) //(0,0)=10 (0,1)=20.......
  17. }
  18. }
  19. }

  数组拷贝和传参

  1. //拷贝
  2. func testArray(){
  3. var a [3]int
  4. a[0] = 10
  5. a[2] = 20
  6. a[3] = 30
  7. b := a //b拷贝了数组a总所有的元素
  8. b[0] = 1000
  9. fmt.Println(a,b) //[10,20,30] [1000,20,30] //拷贝的值相同,内存地址不同
  10. }
  11. //传参
  12. func testArray(){
  13. a := [3]int{10,20,30}
  14. modify(a) //当一个数组作为参数传递时,会将值拷贝一份过去
  15. fmt.Println(a) //[10 20 30]
  16. }
  17. func modify(b [3]int){
  18. b[0] = 1000 //修改此处的值不影响原数据
  19. return
  20. }

八、Slic切片

  定义:是基于数组类型作的一层封装,可以自动扩容  var a []int  //定义一个int类型的切片

  1. //初始化切片
  2. func test(){
  3. a := [5]int{1,2,3,4,5}
  4. var b []int = a[1:4]
  5. fmt.Println(b) //[2 3 4]
  6. }
  7. func test2(){
  8. a := []int{1,2,3}
  9. fmt.Println(a)
  10. }
  11. //切片的基本操作
  12. functest(){
  13. a := []int{1,2,3,4,5,6,7,8}
  14. var b []int = a[2:6] //下标从2到6的元素,不包括6
  15. fmt.Println(b) //[3 4 5 6]
  16. var c []int = a[3:] //从下标为3的元素到最后元素,包括3
  17. fmt.Println(c) //[4 5 6 7 8]
  18. var d []int = a[:5] //下标为0的元素到下标5的元素,包括0但不包括5
  19. fmt.Println(d) //[1 2 3 4 5]
  20. var e []int = a[:] //包括这个数组的所有元素
  21. fmt.Println(e) //[1 2 3 4 5 6 7 8]
  22. //修改切片:切片的修改是对应数组的,改的是数组的内存地址
  23. func test(){
  24. {
  25. a := [..]int{1,2,3,4,5,6,7,8}
  26. b := a[2:5]
  27. b[0] = b[0] + 10
  28. b[1] = b[1] + 10
  29. b[2] = b[2] + 10
  30. fmt,Println(a) //[1,2,13,14,15,6,7,8}
  31. darr := [...]int{1,2,3,4,5,6}
  32. dslice := darrr[2:5]
  33. fmt.Println(“array before”,darr) //{1,2,3,4,5,6}
  34. for i,v:= range dslice{
  35. dslice[i]++
  36. fmt.Println(i,v) //获取到下标i和值v,修改数据要用切片对应的下标进行修改
  37. }
  38. fmt.Println("arraty after",darr) //[1,2,4,5,6,6}
  39. }
  40. //make创建切片
  41. func test(){
  42. a := make([]int,5,10) //5表示长度,10 表示容量,容量从0开始
  43. a[0] = 10
  44. a[1] = 20
  45. a = append(a,30) //长度表示显示长度,容量表示内存容量,切片可以通过append添加,当容量不足时,append还可以对属于组进行扩容,当append扩容的时候,底层为新建一个双倍容量的内存空间,把之前的数组内容拷贝进去
  46. fmt.Println(a) //[10,20,0,0,0,30]
  47. }
  48. func test2(){
  49. a := make([]intt,0,10}
  50. fmt.Println(b,len(b),cap(b))
  51. b = append(b,100)
  52. fmt.Println(b,len(b),cap(b)) //无长度,添加到数组的第一个位置
  53. }
  54. //切片再切片
  55. func test(){
  56. a := [...]string{"a","b","c","d","e","f"}
  57. b := a[1:3[
  58. fmt.Println(b,len(b),cap(b)) //[b,c]长度2,容量5 [b c] 2 5
  59. b = b[:cap(b)]
  60. fmt.Println(b,len(b),cap(b)) //这样切片会让长度=容量==5 [b c d e f] 5 5
  61. }
  62. //空切片和扩展策略
  63. func testnil() {
  64. var a []int
  65. fmt.Println(a, len(a), cap(a))
  66. if a == nil {
  67. fmt.Println("a is nil")
  68. }
  69. a = append(a, 100)
  70. fmt.Printf("%d,%p,len:%d,cap%d\n", a, a, len(a), cap(a)) //[100],0xc0000100a8,len:1,cap1 %p表示内存地址
  71. a = append(a, 200)
  72. fmt.Printf("%d,%p,len:%d,cap%d\n", a, a, len(a), cap(a)) //[100 200],0xc000010100,len:2,cap2
  73. a = append(a, 300)
  74. fmt.Printf("%d,%p,len:%d,cap%d\n", a, a, len(a), cap(a)) //[100 200 300],0xc00000a400,len:3,cap4
  75. a = append(a, 400)
  76. fmt.Printf("%d,%p,len:%d,cap%d\n", a, a, len(a), cap(a)) //[100 200 300 400],0xc00000a400,len:4,cap4
  77. a = append(a, 500)
  78. fmt.Printf("%d,%p,len:%d,cap%d\n", a, a, len(a), cap(a)) //[100 200 300 400 500],0xc00000e280,len:5,cap8
  79. }
  80. //切片传参
  81. func test(){
  82. a := []int{1,2,3}
  83. b := []int{4,5,6}
  84. a = append(a,23,34,45)
  85. fmt.Println(a) //[1,2,3,,23,34,45]
  86. a = append(a,b...)
  87. fmt.Println(a) //[1,2,3,23,34,45,4,5,6]
  88. }
  89. func test2(){
  90. var a []int = []int{1,2,3}
  91. var b []iont = []int{4,5,6}
  92. vvopy(a,b)
  93. fmt.Println(a) //[4,5,6]
  94. fmt.Println(b) //[4,5,6]
  95. var c []int = []int{1,2}
  96. var d []int = []int{4,5,6}
  97. copy(c,d)
  98. fmt.Println(c) //[4,5]
  99. fmt.Println(d) //[4,5,6]
  100. }

九、Map哈希表

  定义:map类型是一个key-value的数据结构

  声明:var a map[key的类型]value类型。如:var a map[string]int  var b map[int]string  var c map[float32]string

  1. //初始化 map必须初始化才能使用
  2. func test(){
  3. var a map[string]int
  4. fmt.Pringf("a:%v\n",a)
  5. if a == nil{ //根据是否为空判断有没有初始化
  6. a = make(map[string]intm,16) //初始化map并定义容量16
  7. fmt.Printf("a=%v\n",a)
  8. a["stu01"]=1000
  9. fmt.Printf("a=%v\n",a) //a = map【sttu01:1000]
  10. }
  11. }
  12. func test2(){
  13. a := map[string]int
  14. "steve":12000, //逗号要加
  15. "jamie":15000
  16. }
  17. a["mike"] = 9000
  18. fmt.Println("a map contents:",a)
  19. }
  20. //map插入操作
  21. func test(){
  22. a := make(map[string]int)
  23. a["steve"] = 12000
  24. a["jamie"] = 15000
  25. a["mike"] = 9000
  26. fmt.Println("a map contents:",a) //a map contents:map[jamie:15000 mike:9000 steve:12000]
  27. }
  28. //通过key访问map中的元素
  29. func test(){
  30. a := map[string]int{
  31. "steve":12000,
  32. "jamie":15000
  33. }
  34. a["mike"] = 9000
  35. b := "jamie"
  36. fmt.Println("Salary of",b,"is","a[b]) //Salary of jamie is 15000
  37. }
  38. //判断map指定的key是否cunzai
  39. func test() {
  40. a := map[string]int{
  41. "stu01": 1000,
  42. "stu02": 2000,
  43. }
  44. b := "joe"
  45. value,ok := a[b] //valuesahib值,ok是布尔类型
  46. if ok == false {
  47. fmt.Printf("key %s is not exisst\n",b)
  48. } else{
  49. fmt.Printf("key %s is %d\n",b,value)
  50. }
  51. }
  52. //遍历map
  53. func test() {
  54. a := map[string]int{
  55. "stu01": 1000,
  56. "stu02": 2000,
  57. }
  58. fmt.Println("all items of a map")
  59. for key,value := range a{
  60. fmt.Printfd("["[%s]=%d\n",key,value)
  61. }
  62. }
  63. //map删除元素
  64. func test() {
  65. a := map[string]int{
  66. "stu01": 1000,
  67. "stu02": 2000,
  68. }
  69. fmt.Println("map before deletion",a)
  70. delete(a,"steve")
  71. fmt.Println("map after deletion",a)
  72. }
  73. //map的长度
  74. func testmap() {
  75. a := map[string]int{
  76. "stu01": 1000,
  77. "stu02": 2000,
  78. }
  79. fmt.Println("length is", len(a))
  80. }
  81. //map是引用类型
  82. func testmap() {
  83. a := map[string]int{
  84. "stu01": 1000,
  85. "stu02": 2000,
  86. }
  87. fmtPrintln("origin map",a)
  88. b := a //b引用了a的内存地址
  89. b["steve"] = 1800 //b变了,a也变了
  90. fmt.Println("a map changed",a)
  91. }
  92. //map排序
  93. func test() {
  94. var a map[string]int = make(map[string]int, 10)
  95. for i := 0; i < 10; i++ {
  96. key := fmt.Sprintf("key%d", i)
  97. a[key] = i
  98. }
  99. var keys []string = make([]string, 0, 10)
  100. for key, value := range a {
  101. fmt.Printf("key:%s = %d\n", key, value) //默认是无序的
  102. keys = append(keys, key) //将map添加到数组中
  103. }
  104. sort.Strings(keys) //将数组排序
  105. for _, value := range keys {
  106. fmt.Printf("key:%s val:%d\n", value, a[value])
  107. }
  108. }
  109. //map类型的切片
  110. func test() {
  111. var mapSlice []map[string]int //定义一个切片中是map
  112. mapSlice = make([]map[string]int, 3, 10) //初始化切片
  113. fmt.Println("before map init")
  114. for index, value := range mapSlice { //遍历切片中的map
  115. fmt.Printf("index:%d value:%v\n", index, value)
  116. }
  117. fmt.Println()
  118. mapSlice[0] = make(map[string]int, 10) //初始化map
  119. mapSlice[0]["a"] = 1000
  120. mapSlice[0]["b"] = 2000
  121. fmt.Println("after map init")
  122. for index, value := range mapSlice { //遍历切片中的map
  123. fmt.Printf("index:%d value:%v\n", index, value)
  124. }
  125. }
  126. func test() {
  127. var s map[string][]int //定义一个map中是切片
  128. s = make(map[string][]int, 16) //初始化map
  129. key := "stu01" //定义一个键
  130. value, ok := s[key] //判断该键的切片是否存在
  131. if !ok { //如果不存在则初始化该键对应的切片
  132. s[key] = make([]int, 0, 16)
  133. }
  134. value = append(value, 100)
  135. value = append(value, 200)
  136. s[key] = value //将value赋值s[key]
  137. fmt.Printf("map:%v\n", s)
  138. }

十、Struct结构体

  定义:go中面向对象时通过struct来实现的

  1. //struct初始化方法
  2. type User struct {
  3. Username string
  4. Sex string
  5. Age int
  6. AvatarUrl string
  7. }
  8. func test(){
  9. //方法一
  10. var user User
  11. user.Age = 18
  12. user.Username = "user01"
  13. user.Sex = "男"
  14. user.AvatarUrl = "www.baidu.com"
  15. //方法二
  16. var user User = User{
  17. Username : "user01"
  18. Age : 18
  19. Sex : "男"
  20. AvatarUrl : www.baidu.com
  21. }
  22. //方法三
  23. user := User{
  24. Username : "user01"
  25. Age : 18
  26. Sex : "男"
  27. AvatarUrl : www.baidu.com
  28. }
  29. fmt.Printf("user.name=%s age=%d sex=%s avatar=%s\n", user.Username, user.Age, user.Sex, user.AvatarUrl)
  30. }
  31. //结构体类型的指针
  32. var user *User = &User{}
  33. fmt.Printf("%p %#v\n",user)
  34. var user *User = &User{
  35. Username : "user01"
  36. Age : 18
  37. Sex : "男"
  38. AvatarUrl : www.baidu.com
  39. }
  40. var user User = new(User)
  41. Username = "user01"
  42. Age = 18
  43. Sex = "男"
  44. AvatarUrl = www.baidu.com
  45. func test() {
  46. var user *User
  47. fmt.Printf("user=%v\n", user) //user=<nil>
  48. var user01 *User = &User{}
  49. user01.Age = 18
  50. user01.Username = "user01"
  51. fmt.Printf("user01=%#v\n", user01) //user01=&main.User{Username:"user01", Sex:"", Age:18, AvatarUrl:""}
  52. }

  struct的内存布局以及构造函数

  1. //结构体的内存布局:占用一段连续的内存空间
  2. type Test struct{
  3. A int32
  4. B int32
  5. C int32
  6. D int32
  7. }
  8. func test(){
  9. var t Test
  10. fmt.Printf("a addr:%p\n", &t.A) a addr:0xc000062070
  11. fmt.Printf("b addr:%p\n", &t.B) b addr:0xc000062074
  12. fmt.Printf("c addr:%p\n", &t.C) c addr:0xc000062078
  13. fmt.Printf("d addr:%p\n", &t.D) d addr:0xc00006207c
  14. } //每块占用4字节,在内存中连续
  15. //无构造函数,需要自己定义
  16. import "导入user包"
  17. func main(){
  18. var u user.User
  19. u.Age = 18
  20. fmt,Printf("user.%#v\n",u)
  21. }
  22. package user
  23. type User struct{
  24. Username string
  25. Sex string
  26. Age int
  27. AvatarUrl string
  28. }

  匿名字段和struct嵌套

  1. //匿名字段:没有定义名字的字段
  2. type User struct{
  3. Username string
  4. Sex string
  5. Age int
  6. AvatarUrl string
  7. int //匿名字段
  8. string //匿名字段
  9. }
  10. func main(){
  11. var u User
  12. u.Username = "user01"
  13. u.Sex = "man"
  14. u.int = 100
  15. u.string = "hello"
  16. fmt.Printf("user=%#v\n“,u”)
  17. }
  18. //匿名字段默认采用类型名作为字段名
  19. type Address struct{
  20. Province string
  21. City string
  22. }
  23. type User struct{
  24. Username string
  25. Sex string
  26. &Address
  27. }
  28. func test()[
  29. var user User
  30. user.Username = "user"
  31. user.Sex = "man"
  32. user.Address = &Address{ //第一种方式
  33. Province : "北京",
  34. City : "北京",
  35. }
  36. user.Province = "北京" //第二种方式
  37. user.City = "北京"
  38. }
  39. //匿名字段冲突
  40. type Address struct{
  41. Province string
  42. City string
  43. }
  44. type User struct{
  45. City string
  46. Username string
  47. Sex string
  48. *Address
  49. }
  50. func test()[
  51. var user User
  52. user.Username = "user"
  53. user.Sex = "man"
  54. user.City = "北京"
  55. fmt.Printf("user=%#v\n",user)
  56. user.Address = new(Address) //指针必须初始化
  57. fmt.Printf("user=%#v\n",user)
  58. user.Address.City = "北京"
  59. fdmt.Printf("user=%#v city of address:%s\n",user,user.Address.City)

  结构体链表

    单链表定义:每个节点包含下一个节点的地址,这样把所有的节点串起来叫做单链表,第一个节点叫做链表头

    双链表定义:如果两个指针分别指向前一个节点和后一个节点,就是双链表

  1. //单链表
  2. type Studfent struct()[
  3. Name string
  4. Next *Student
  5. }
  6. //双链表
  7. type Student struct{
  8. Name string
  9. Next *Student
  10. Preve *Student
  11. }

  结构体二叉树

    定义:如果每个节点有两个指针分别用来是想左子树和柚子树,这样的结构就是二叉树

  1. type Student struct{
  2. Name string
  3. Age int
  4. Score float64
  5. Left *Student
  6. Right *Student
  7. }
  8. func trans(root *Student){
  9. if root == nil{
  10. return
  11. }
  12. fmt.Println(root) //前序遍历
  13. trans(root.Left)
  14. trans(root.Right)
  15. }
  16. func main(){
  17. var root *Student = new(Student)
  18. root.Name = "stu01"
  19. root.Age = 19
  20. root.Score = 100
  21. var left1 *Student = new(Student)
  22. left1.Name = "stu02"
  23. left1.Age = 19
  24. ledt1.Score = 100
  25. root.Left = left1
  26. var rigtht1 *Student = new(Student)
  27. right1.Name = "stu04"
  28. right1.Age = 19
  29. right1.Score = 100
  30. root.Right = right1
  31. var left2 *Student = new(Student)
  32. left2.Name = "stu02"
  33. left.Age = 19
  34. left.Score = 100
  35. left2.Score = 100
  36. left1.left = left2
  37. trans(root)
  38. }
  39. //&{stu01 19 100 0xc000078330 0xc000078360}
  40. //&{stu02 19 100 0xc000078390 <nil>}
  41. //&{stu03 19 100 <nil> <nil>}
  42. //&{stu04 19 100 <nil> <nil>}
  43. func trans(root *Student){
  44. if root == nil{
  45. return
  46. }
  47. trans(root.left)
  48. fmt.Println(root) //中序遍历
  49. trans(root.right)
  50. }
  51. //&{stu03 19 100 <nil> <nil>}
  52. //&{stu02 19 100 0xc000078390 <nil>}
  53. //&{stu01 19 100 0xc000078330 0xc000078360}
  54. //&{stu04 19 100 <nil> <nil>}
  55. func trans(root *Student){
  56. if root == nil{
  57. return
  58. }
  59. trans(root.left)
  60. trans(root.right)
  61. fmt.Println(root) //后序遍历
  62. }
  63. //&{stu03 19 100 <nil> <nil>}
  64. //&{stu02 19 100 0xc000078390 <nil>}
  65. //&{stu04 19 100 <nil> <nil>}
  66. //&{stu01 19 100 0xc000078330 0xc000078360}

  工厂模式

    定义:golang中struct没有构造函数,可以用工厂模式来解决这个问题

  1. //简单工厂模式
  2. package easyfactory
  3. import "errors"
  4. type operation struct{
  5. }
  6. type cal interface(
  7. cal(int,int) (float64,error)
  8. }
  9. type operationAdd struct{
  10. operation
  11. }
  12. func (o *operationAdd) cal(num1,num2 int) (float64,error) {
  13. return float64(num1+num2),nil
  14. }
  15. type operationMinus struct {
  16. operation
  17. }
  18. func (o *operationMinus) cal(num1,num2 int) (float64,error) {
  19. return floaf64(num1-num2),nil
  20. }
  21. type operationMulti struct {
  22. operation
  23. }
  24. func (o *operationMulti) cal(num1,num2 int) (float,errror) {
  25. return float64(num1 * num2),nil
  26. }
  27. type operationDiv struct{
  28. operation
  29. }
  30. func (o *operationDiv) cal(num1,num2 int) (float64,error) {
  31. if num2 == 0{
  32. return 0,errors.New("除法运算中除数不能为0")
  33. }
  34. return float64(num1/num2),nil
  35. }
  36. type operationFactory struct{}
  37. func (o *operationFactory) createOperation(op string) cal {
  38. switch op{
  39. case "+":
  40. return new(operationAdd)
  41. case "-":
  42. return new(operationMinus)
  43. case "*":
  44. return new(operationMulti)
  45. case "/":
  46. return new(operationDiv)
  47. }
  48. return nil
  49. }

  struct和tag应用

    定义:tag是结构体的原信息,可以运行的时候通过反射的机制读取出来,字段类型后面,以反引号的key:value结构的字符串,多了tag以逗号隔开

  1. type User struct{
  2. Username string `json:"username"`
  3. Sex string `json:"sex"`
  4. Score float32
  5. }
  6. func main(){
  7. user := & User {
  8. Username:"user01",
  9. Sex:"男",
  10. Score: 84,
  11. }
  12. data,_ := json.Marshal(user) //第二个接收的数据是错误,为nil
  13. fmt.Printf("json str:%s\n",string(data))
  14. }

  方法

    定义:go的方法是在函数面前加上一个接收者,这样编译器就知道这个方法属于哪个类型

  1. type A struct{
  2. }
  3. func (a A) Test(s string){ //通过a来访问A的实例中的成员变量,也就是struct的字段
  4. }
  5. func main(){
  6. var t A
  7. t.Test() //调用方法
  8. }
  9. type People struct{
  10. Name string
  11. Country string
  12. }
  13. func (p People) Print() {
  14. fmt.Printf("name=%s country=%s\n",p.Name,p.Country)
  15. }
  16. func (p People) Set(name,country string) {
  17. p.Name = name
  18. p.Country = country
  19. }
  20. func test() {
  21. var p1 People = People{
  22. Name : "pe01",
  23. Country : "china",
  24. }
  25. p1.Print() //pe01 china
  26. p1.Set("pe02","Ch")
  27. p1.Print() //pe01 china Set修改的数据通过值拷贝传出,原地址数据不变
  28. }
  29. //可以为当前包内定义的任何类型增加方法
  30. type Integer int //创建Integer为int的别名
  31. func (i Integer) Print() {
  32. fmt.Println(i)
  33. }
  34. func test() {
  35. var a Integer //设定一个变量为Integer类型
  36. a = 1000
  37. a.Print() //调用int自定义的Print方法
  38. var b int = 200
  39. a = Integer(b)
  40. a.Print()
  41. }

  值类型和指针类型

  1. type People struct {
  2. Name string
  3. Country string
  4. }
  5. func (p People) Print() {
  6. fmt.Printf("name=%s country=%s\n",p.Name,p.Country)
  7. }
  8. func (p *People Set(name,country string) {
  9. p.Name = name
  10. p.Country = country
  11. }
  12. func test() {
  13. var p1 People = People{
  14. Name:"pe01",
  15. Country:"china",
  16. }
  17. p1.Print()
  18. (&p1).Set2("pe02","Ch") //指针地址内容改变,所以数据改变,也可以写成p1.Set("pe02","Ch")
  19. p1.Print()
  20. }

  匿名字段和继承

  1. type Animal struct{
  2. Name string
  3. Sex string
  4. )
  5. func (a *Animal) Talk() {
  6. fmt.Printf("i,talk,i'm %s\n",a.Name)
  7. }
  8. type Dog struct{
  9. Feet string
  10. *Animal //或者Animal 通过组合来实现继承
  11. }
  12. func (d *Dog)Eat() {
  13. fmt.Println("dog is eat")
  14. }
  15. func test() {
  16. var d *Dog &Dog{
  17. Feet:"four feet",
  18. Animal:&Animal{
  19. Name:"dog",
  20. Sex:"xiong"
  21. },
  22. }
  23. d.Eat()
  24. d.Talk()
  25. }

  多重继承与冲突解决

  1. type Dog struct{
  2. Feet string
  3. *Animal1
  4. *Animal2
  5. }
  6. type Animal1 struct {
  7. Name string
  8. Sex string
  9. }
  10. func (a *Animal1) Talk(){
  11. fmt.Printf("i,talk,i'm %s\n",a.Name)
  12. }
  13. type Animal2 struct {
  14. Name string
  15. Sex string
  16. }
  17. func (p *Animal2) Talk(){
  18. fmt.Println("Animal2")
  19. }
  20. func test() {
  21. var d *Dog = &Dog{
  22. Feet:"four feet",
  23. Animal1:&Animal1{
  24. Name:"dog",
  25. Sex:"xiong",
  26. },
  27. }
  28. d.Animal1.Talk()
  29. d.Animal2.Talk()
  30. }

  结构体和Json序列化

  1. //序列化 struct转json
  2. import "encoding/json"
  3. type Student struct{
  4. Id int
  5. Name string
  6. Sex string
  7. }
  8. type Class struct{
  9. Name string
  10. Count int
  11. Student []*Student
  12. }
  13. func test(){
  14. c := &Class{
  15. Name:"101",
  16. Count:0,
  17. }
  18. for i:= 0,i<10;i++{
  19. stu := &Student{
  20. Name :fmt.Sprintf("stu%d",i),
  21. Sex :"man",
  22. Id:i,
  23. }
  24. c.Student = append(c.Student,stu)
  25. }
  26. data,err := json.Marshal(c)
  27. if err != nil{
  28. fmt.Println("json marashal failed")
  29. return
  30. }
  31. fmt.Printf("json:%s\n",string(data))
  32. }
  33. //反序列化 json装struct
  34. type Student struct{
  35. Id int
  36. Name string
  37. Sex string
  38. }
  39. type Class struct{
  40. Name string
  41. Count int
  42. Student []*Student
  43. }
  44. var rawJson = `{"Name":"101","Count":0,"Student":[
  45. {"Id":0,"Name":"stu0","Sex":"man"},{"Id":1,"Name":"stu1","Sex":"man"},
  46. {"Id":2,"Name":"stu2","Sex":"man"},{"Id":3,"Name":"stu3","Sex":"man"},
  47. {"Id":4,"Name":"stu4","Sex":"man"},{"Id":5,"Name":"stu5","Sex":"man"},
  48. ]
  49. }`rint
  50. var c1 *Class = &Class{}
  51. err := json.Unmarshal([]byte(rawJson),c1)
  52. if err != nil{
  53. fmt.Println("unmarshal failed")
  54. return
  55. }
  56. fmt.Printf("c1:%#v\n",c1)
  57. /*c1:&main.Class{
  58. Name:"101", Count:0, Student:[]*main.Student{
  59. (*main.Student)(0xc00007a510), (*main.Student)(0xc00007a540),
  60. (*main.Student)(0xc00007a570), (*main.Student)(0xc00007a5a0),
  61. (*main.Student)(0xc00007a600), (*main.Student)(0xc00007a630),
  62. }*/
  63. for _,v := range c1.Student{
  64. fmt.Printf("stu:%#v\n",v)
  65. /*stu:&main.Student{Id:0, Name:"stu0", Sex:"man"}
  66. stu:&main.Student{Id:1, Name:"stu1", Sex:"man"}
  67. stu:&main.Student{Id:2, Name:"stu2", Sex:"man"}
  68. stu:&main.Student{Id:3, Name:"stu3", Sex:"man"}
  69. stu:&main.Student{Id:4, Name:"stu4", Sex:"man"}
  70. stu:&main.Student{Id:5, Name:"stu5", Sex:"man"}*/
  71. }
  72. }

十一、时间和日期

  使用time包中的time.Time类型用来表示时间

  获取当前时间:

    now := time.Now()  获取当前时间

    now := time.Now().Day()

    now := time.Now().Minute()

    now := time.Now().Month()

    now := time.Now().Year()

  格式化:

  1. func main(){
  2. now := time.Now()
  3. fmt.Printf("current time:$v\n",now)
  4. tear := now.Year()
  5. month := now.Month()
  6. day := now.Day()
  7. hour := now.Hour()
  8. minute := now.Minute()
  9. send := now.Second()
  10. fmt.Printf("%02d-%02d-%02d-%02d-%02d-%02d", year, month, day, hour, minute, send)
  11. }

  定时器

  1. func main(){
  2. ticker := time.Tick(5*time.Second) //每5s执行一次其中的函数
  3. for i := range ticker{
  4. fmt.Printf("%v\n",i)
  5. 函数()
  6. }
  7. }

  格式化

  1. func main(){
  2. now := time.Now()
  3. fmt.Println(now.Format("02/1/2006 15:04"))
  4. fmt.Println(now.Format("2006/1/02 15:04"))
  5. fmt.Println(now.Format("2006/1/02"))
  6. }
  7. //格式可以换,时间必须为2006 1 02 15:04

  计算程序运行时间

  1. func main(){
  2. start := time.Now().UnixNano()
  3. for i := 0;i<10;i++{
  4. time.Sleep(time.Millisecond)
  5. }
  6. end := time.Now().UnixNano()
  7. cost := (end - start)/1000000 //微秒化成秒
  8. fmt.Printf("%vn",cost)
  9. }

十二、if-else

  1. //分支结构
  2. func main(){
  3. age := 19
  4. if age >18{
  5. fmt.Println("澳门赌场")
  6. }else if age <18{
  7. fmt.Println("Waring...")
  8. }else{
  9. fmt.Println("成年了")
  10. }
  11. }
  12. //特殊写法
  13. func main(){
  14. age := 18
  15. if age ==18{
  16. fmt.Println("成年”)
  17. }
  18. if age2 := 28;age2 >18{
  19. fmt.Println("成年了")
  20. }
  21. fmt.Println(age2) //报错,在判断条件中定义变量无法在判断条件外打印
  22. }

十三、switch-case

  定义:用于if条件多时

  1. //每个switch只能有一个default分支
  2. func test(){
  3. t:=3
  4. switch t{
  5. case 1 : //如果条件t是1则执行
  6. fmt.Println("大拇指")
  7. case 2 : //如果条件t是2则执行
  8. fmt.Println("食指")
  9. default: //否则输出
  10. fmt.Println("无效的输入")
  11. }
  12. //一个分支可以有多个值,之间用逗号分隔
  13. func test2(){
  14. switch t := 7;t{
  15. case 1,3,5,7,9:
  16. fmt.Println("奇数")
  17. case 2,4,6,8:
  18. fmt.Println("偶数")
  19. default:
  20. fmt.Println(n)
  21. }
  22. }
  23. //分支可以使用表达式,此时switch后不需要再跟判断变量
  24. func test3(){
  25. age :=30
  26. switch {
  27. case age <25:
  28. fmt.Println("好好学习")
  29. case age >25:
  30. fmt.Println("好好工作")
  31. case age >60:
  32. fmt.Println("活着真好")
  33. }
  34. }
  35. //fallthrough语法可以执行满足条件的case的下一个case,是为了兼容c语言中的case设计的
  36. func test4(){
  37. s := "a"
  38. switch{
  39. case s == "a" : //成立
  40. fmt.Println("a")
  41. fallthrough //无条件的执行下一个case语句
  42. case s =="b":
  43. fmt.Println("b")
  44. case s=="c":
  45. fmt.Println("c")
  46. default:
  47. fmt.Println("...")
  48. }
  49. }

十四、for

  1. //for循环
  2. for 初始语句;条件表达式;结束语句{
  3. 循环体语句
  4. }
  5. func test(){
  6. a := 3
  7. for i := 0;i<a;i++{ //定义i=0,如果i<a,则成立执行循环,循环结束后i++
  8. fmt.Println(i)
  9. }
  10. }
  11. //无线循环
  12. for {
  13. 循环体语句
  14. } //可以通过break,goto,return,panic强制退出

  for range:键值循环

    数组:返回索引和值  切片:返回索引和值  字符串:返回索引和值  map:返回键和值  通道(channel):只返回通道内的值

十五、goto/continue/break

  break:退出当前循环,后加标签直接退出到标签处

  continue:返回执行下一次循环,后加标签循环下一次的标签处

  goto:通过标签进行代码间的无条件跳转,可以快速跳出循环,避免重复退出

  1. //goto
  2. func test(){
  3. for i := 0;i<5;i++{
  4. for j:=0;j<3;j++{
  5. if i == 2 && j == 2{
  6. goto yhc //直接跳转到yhc
  7. }
  8. }
  9. }
  10. fmt.Println("两层for循环结束")
  11. yhc : //定义一个标签label
  12. }

  

转载于:https://www.cnblogs.com/parallel-Y/p/11311603.html

发表评论

表情:
评论列表 (有 0 条评论,99人围观)

还没有评论,来说两句吧...

相关阅读

    相关 go语言基本数据类型

    Go语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map、通道(channel)等。Go 语言的基本类型和其他语言大同小异。

    相关 四、Go 语言数据类型

    在 Go 编程语言中,数据类型用于声明函数和变量。 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存。