变量

  1. 变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。
  2. 通过变量名访问变量中的数据
  3. Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。
  4. 声明变量的一般形式是使用 var 关键字:
  5. 例子:
  6. 常规定义: var 变量名称 type
  7. 自动推导: 变量名称 := (数据函数中使用)
  8. 组合:
  9. var (
  10. a,b string
  11. c bool
  12. d int
  13. )
  14. var e,f = 123, "1234"
  15. 函数中使用:
  16. g, h := 123, "hello"

基础数据类型

int,bool,string,bytes

派生据类型

一维数组

  1. // 一维数组
  2. // 输出数据类型
  3. var names [1]string
  4. fmt.Printf("%T\n", names)
  5. // 实例 使用... 自动推导后面的数据得到数组长度
  6. name := [...]string{"1", "2", "123", "3", "4", "5"}
  7. fmt.Printf("%T", name)
  8. fmt.Println(name)
  9. // 取值
  10. fmt.Println("切片的值为:", name[2])
  11. // 对指定位置的数据进行初始化 如下对长度为"3,1,4" 位置的数据进行修改
  12. passwd := [10]int{3: 1111, 1: 222, 4: 333}
  13. fmt.Println("访问和修改,长度为3的值:", passwd[3])
  14. // 获取数组的长度 长度为10
  15. fmt.Println("数组长度:", len(passwd))
  16. // 数组切片
  17. groups := [...]string{"python", "golang", "java", "C#", "groovy"}
  18. fmt.Println(groups[2:3]) // [开始:结束]
  19. // 遍历数组
  20. for i := 0; i < len(groups); i++ {
  21. fmt.Printf("第[%d]位数: %s\n", i, groups[i])
  22. }
  23. // 第二种遍历
  24. for i, v := range groups {
  25. fmt.Printf("[%d]: %s\n", i, v)
  26. }

多维数组

  1. // 多维数组
  2. // 多为数组的长度只有一维可以自动推导,二维必须定义长度
  3. langes1 := [...][3]string{{"golang", "python", "groovy"}, {"java", "golang", "C++"}}
  4. langes2 := [3][3]string{{"windows项目", "shell", "groovy"}, {"java", "golang", "C++"}}
  5. langes3 := [3][3]string{0: {"windows项目", "shell", "groovy"}, 2: {"java", "golang", "C++"}}
  6. langes4 := [4][3]string{0: {0: "windows项目", 2: "shell", 1: "groovy"}, 1: {"java", "golang", "C++"}, 3: {"php", "javascriptr", "html"}}
  7. // 输出类型
  8. fmt.Printf("数组: \n%T\n%T\n%T\n%T\n", langes1, langes2, langes3, langes4)
  9. // 输出值
  10. fmt.Printf("%q\n", langes1)
  11. // 多为数组访问
  12. devops := langes1[0][0:2]
  13. fmt.Printf("运维开发需要掌握的语言:%s\n", devops)
  14. dev := langes2[1][0:3] // 一般结束位都需要按照下标+1
  15. fmt.Printf("开发需要掌握的语言:%s\n", dev)
  16. // 多维数组修改
  17. fmt.Printf("更正前- 运维开发需要掌握的语言为:%s\n", langes1[0])
  18. langes1[0][2] = "shell"
  19. fmt.Printf("更正后- 运维开发需要掌握的语言为:%s\n", langes1[0])
  20. fmt.Println("----------------------")
  21. fmt.Printf("更正前- 运维开发需要掌握的技能为:%s\n", langes2[0])
  22. langes2[0] = [3]string{"linux", "database", "CICD"}
  23. fmt.Printf("更正后- 运维开发需要掌握的技能为:%s\n", langes2[0])
  24. // 多维数组遍历
  25. // langes3 := [3][3]string{0: {"windows项目", "shell", "groovy"}, 2: {"java", "golang", "C++"}}
  26. for i, line := range langes3 {
  27. // pkg_fmt.Printf("第一次遍历:%s\n", line)
  28. for ii, vv := range line {
  29. // pkg_fmt.Printf("第二次遍历: %s\n", vv)
  30. fmt.Printf("langes3数组中的值为:[%d %d %s]\n", i, ii, vv) // 此处需要多注意
  31. }
  32. }
  33. // 多为数组遍历第二遍测试
  34. for i, line := range langes1 {
  35. // pkg_fmt.Printf("第一次遍历:%s\n", line)
  36. for ii, vv := range line {
  37. // pkg_fmt.Printf("第二次遍历: %s\n", vv)
  38. fmt.Printf("langes1数组中的值为:[%d %d %s]\n", i, ii, vv) // 此处需要多注意
  39. }
  40. }

切片

  1. // 切片 切片是长度可变的数组,数组在定义好之后长度不可变
  2. // 声明切片 nil切片
  3. var slice1 []string
  4. fmt.Printf("%T,%t,%v\n", slice1, slice1 == nil, slice1)
  5. // 初始化 使用make函数初始化切片
  6. slice2 := make([]string, 10)
  7. slice3 := []string{"1", "3", "2"}
  8. arrs := [...][3]string{{"golang", "python", "groovy"}, {"java", "golang", "C++"}}
  9. // 切片类型
  10. fmt.Printf("切片:%q 类型: %T\n", slice3, slice3)
  11. // 切片类型
  12. fmt.Printf("切片:%T, 无固定长度\n", slice2)
  13. // 数组类型
  14. fmt.Printf("数组:%T, 必须有长度\n", arrs)
  15. /*
  16. 切片和数组的区别:
  17. 数组是长度固定的元素序列 切片:[]string
  18. 切片是长度可变的元素序列 数组:[2][3]string
  19. */
  20. /*
  21. 切片初始化后才能用 否则无法使用
  22. make([]数据类型, 长度, 步长)
  23. */
  24. stu := make([]string, 3, 5)
  25. fmt.Printf("步长: %d\n长度: %d\n", len(stu), cap(stu))
  26. fmt.Printf("%q,%q\n", stu[0], stu[1:5])
  27. // 切片定义
  28. stu2 := []string{"golang", "java", "python", "C#", "C++"}
  29. // 修改切片中的值
  30. stu[0] = "golang"
  31. stu[1] = "python"
  32. fmt.Printf("%q,%q\n", stu[0], stu[1])
  33. fmt.Printf("%T : %q\n", stu2, stu2)
  34. // 切片遍历第一种方式
  35. for index, value := range stu2 {
  36. fmt.Printf("切片第一种遍历: %d %s\n", index, value)
  37. }
  38. // 切片遍历第二种方式
  39. for i := 0; i < len(stu2); i++ {
  40. fmt.Printf("切片第二种遍历: %s\n", stu2[i])
  41. }
  42. // 切片添加元素 append
  43. stu2 = append(stu2, "shell")
  44. fmt.Println(stu2)
  45. // 可以将string拼接到byte切片
  46. slice := make([]byte, 10)
  47. var a string = "Hi "
  48. var b string = "YY"
  49. slice = append([]byte(a), b...)
  50. fmt.Println("切片追加,解包的方式: ", string(slice))
  51. /*
  52. 切片删除元素
  53. stu2[start:end] stu2中,从start开始到end-1所有元素组成的切片
  54. 以索引进行删除
  55. */
  56. stu2 = stu2[0:4]
  57. fmt.Println(stu2)
  58. // 删除第一个元素,删除最后一个元素
  59. // 切片定义
  60. stu3 := []string{"golang", "java", "python", "C#", "C++"}
  61. stu4 := stu3[1:len(stu3)]
  62. fmt.Println(stu3)
  63. fmt.Printf("stu4: %s\n", stu4)
  64. stu5 := stu3[0:len(stu3)]
  65. fmt.Printf("stu5: %s\n", stu5)
  66. // 删除中间一个数据 删除3
  67. nums1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
  68. // copy(dst,src) src > dst
  69. nums2 := []int{10, 11, 12, 13, 15, 15, 16}
  70. copy(nums1, nums2) // 按照索引进行复制对应起来
  71. fmt.Println(nums1, nums2)

映射

  1. // 映射map 类似py字典
  2. // 定义map 第一种
  3. // 声明定义
  4. var Iaas map[string]string
  5. Iaas = map[string]string{"name": "alinx", "age": "28", "site": "cn"}
  6. /*
  7. 直接使用make进行初始化创建map
  8. 定义map 第二种
  9. */
  10. man := make(map[string]string)
  11. fmt.Printf("%T,%q\n%T\n", Iaas, Iaas, man)
  12. // 定义map 第三种
  13. wom := map[string]string{}
  14. fmt.Printf("%T\n", wom)
  15. // 操作map
  16. langes := map[string]string{"dev": "golang,java,,,,python", "ops": "shell,python,golang", "devops": "golang,shell"}
  17. fmt.Println(strings.Split(langes["dev"], ",")) // 数据分割
  18. fmt.Printf("长度: %d\n", len(langes))
  19. // map 获取值
  20. dev, ok := langes["dev"]
  21. fmt.Printf("map取值:\n 存在吗:%t\n 取出值:%v\n", ok, dev)
  22. // 修改值
  23. langes["ops"] = "java,C++"
  24. fmt.Printf("修改后的值:%s\n", langes)
  25. // 删除值
  26. delete(langes, "dev")
  27. fmt.Printf("删除后的值:%s\n", langes)
  28. // 遍历map(映射)
  29. for k, v := range langes {
  30. fmt.Printf("遍历map数据: %s %s\n", k, v)
  31. }

列表

  1. package main
  2. import (
  3. "container/list"
  4. "fmt"
  5. )
  6. func main() {
  7. // 列表的定义
  8. var name list.List // 生成列表类型
  9. names := list.New() // 返回列表对应的指针
  10. fmt.Printf("%T,%#v\n", name,name)
  11. fmt.Printf("%T,%#v\n", names,names)
  12. for i := 1; i < 10; i++ {
  13. names.PushBack(i)
  14. }
  15. //插入值
  16. first := names.PushFront(0)
  17. // 删除值
  18. names.Remove(first)
  19. // 遍历值
  20. // Front函数获取列表的头元素 Next() 函数依次往下遍历
  21. for l := names.Front(); l != nil ; l = l.Next() {
  22. fmt.Print(l.Value, " ")
  23. }
  24. }


结构体

认识结构体

  1. package main
  2. import "fmt"
  3. /* 结构体是一些列属性组成的复合数据类型,每个属性都具有名称
  4. 语法:
  5. type TypeName formatter
  6. */
  7. // 基于现有数据类型定义结构体
  8. type Counters int
  9. var num int = 10
  10. // 基于现有类型定义
  11. type User map[string]string
  12. // 别名类型定义
  13. type Counter = int
  14. // 函数类型定义
  15. type Callback func() error
  16. func main() {
  17. var counter Counter
  18. fmt.Printf("%T,%v\n", counter, counter)
  19. // var user User
  20. // user["id"] = "1" //无法直接赋值,需要使用make初始化之后才能使用
  21. var user User = make(User)
  22. user["id"] = "1"
  23. fmt.Printf("%T,%v\n", user, user)
  24. // 函数类型使用
  25. callbacks := map[string]Callback{}
  26. callbacks["users"] = func() error {
  27. fmt.Println("add")
  28. return nil
  29. }
  30. // 调用 函数类型结构体
  31. callbacks["users"]()
  32. // 特殊类型 别名
  33. var (
  34. r rune
  35. b byte
  36. )
  37. fmt.Printf("%T, %T", r, b)
  38. }

结构体组合

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. // 组合类型结构体
  7. type User struct {
  8. // 定义结构体属性
  9. id int
  10. name string
  11. addr string
  12. tel string
  13. birthday time.Time
  14. }
  15. func main() {
  16. // 定义结构体类型的变量
  17. var user User
  18. // 零值是由各元素的零值组成的一个结构体的变量
  19. fmt.Printf("%T,%#v\n", user, user)
  20. // 字面量初始化方式( 必须严格按照结构体定义顺序指定 ,且每一个属性都必须指定值)
  21. user = User{10, "alinx", "xxxx", "138", time.Now()}
  22. fmt.Printf("%T,%#v\n", user, user)
  23. // 按照属性名定义字面量,可以无序
  24. user = User{id: 1, name: "alinxsss", addr: "999", tel: "112123123"}
  25. fmt.Printf("%T, %#v\n", user, user)
  26. // 属性访问和修改
  27. // 访问
  28. fmt.Println(user.id)
  29. fmt.Println(user.name)
  30. fmt.Println(user.tel)
  31. // 修改
  32. user.id = 9999
  33. user.name = "good"
  34. user.birthday = time.Now()
  35. fmt.Printf("%T, %#v\n", user, user)
  36. }

结构体指针

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. // 面向对象: 封装,继承,多态
  7. // 结构体类似与面向对象中的类定义
  8. /*
  9. 结构体 => 类
  10. 构造函数 => 创建类对于的实例
  11. 方法
  12. */
  13. type User struct {
  14. id int
  15. name string
  16. tel string
  17. addr string
  18. birthday time.Time
  19. }
  20. // New函数定义 ,定义一个结构体
  21. func NewUser(id int, name, tel, addr string, birthday time.Time) User {
  22. return User{id, name, tel, addr, birthday}
  23. }
  24. // 指针类使用方式
  25. // func NewUser(id int, name, tel, addr string, birthday time.Time) *User {
  26. // return &User{id, name, tel, addr, birthday}
  27. // }
  28. func main() {
  29. // 结构体指针
  30. // 指针类型,直接取地址 &引用
  31. // var user *User = &User{id: 999, name: "alinx"}
  32. // *User 可以省略
  33. var user = &User{id: 888, name: "Love"}
  34. fmt.Printf("%T\n%#v", user, user)
  35. // 结构体 new函数初始化
  36. user = new(User)
  37. fmt.Printf("%T\n,%#v\n", user, user)
  38. u2 := new(User)
  39. fmt.Printf("%T,\n%#v\n", u2, u2)
  40. // 属性访问
  41. fmt.Println(u2.name)
  42. u2.id = 9999999999
  43. u2.name = "gooooood"
  44. fmt.Println(u2.name, u2.id)
  45. u3 := NewUser(1, "2222", "", "", time.Now())
  46. fmt.Printf("%T,%#v\n", u3, u3)
  47. }

匿名结构体

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. c := func() {
  8. fmt.Println("匿名函数")
  9. }
  10. fmt.Printf("%T\n", c)
  11. // 匿名结构体, 一般用于配置类
  12. var user struct {
  13. id int
  14. name string
  15. tel string
  16. addr string
  17. birthday time.Time
  18. }
  19. fmt.Printf("%T,%#v\n", user, user)
  20. user.id = 123
  21. user.name = "sadfasdf"
  22. fmt.Printf("%T,%#v\n", user, user)
  23. // 初始化,零值,字面量 使用
  24. user = struct {
  25. id int
  26. name string
  27. tel string
  28. addr string
  29. birthday time.Time
  30. }{111, "alinx", "123123", "sdddd", time.Now()} // 结构体类型
  31. fmt.Printf("%T,%#v\n", user, user)
  32. // 定义时 就进行初始化
  33. var u2 struct {
  34. id int
  35. name string
  36. } = struct {
  37. id int
  38. name string
  39. }{123, "alinx"}
  40. fmt.Printf("%T,%#v\n", u2, u2)
  41. // 简写 指针加&即可 , 一般作为数据传递
  42. var u2 = struct {
  43. id int
  44. name string
  45. }{id: 111, name: "ddd"}
  46. fmt.Printf("%T,%#v\n", u2, u2)
  47. var u2 = &struct {
  48. id int
  49. name string
  50. }{id: 111, name: "ddd"}
  51. fmt.Printf("%T,%#v\n", u2, u2)
  52. }

组合结构体

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. type Addr struct {
  7. province string
  8. street string
  9. no string
  10. }
  11. type Tel struct {
  12. prefix string
  13. number string
  14. }
  15. // 命名组合(嵌入)
  16. type User struct {
  17. id int
  18. name string
  19. addr *Addr // 组合Addr结构体
  20. tel *Tel // 组合Tel结构体
  21. birthday time.Time
  22. }
  23. func main() {
  24. // 初始化使用
  25. var user User = User{id: 1, name: "alinx", addr: &Addr{}, tel: &Tel{}, birthday: time.Now()}
  26. fmt.Printf("%T,%#v", user, user)
  27. // 写入 和读取 如果是指针就加指针进行调用即可 &Addr
  28. var users User = User{addr: &Addr{province: "贵州省"}}
  29. // 访问
  30. fmt.Println(users.addr.province)
  31. // pkg_fmt.Printf("%T,%#v", users, users)
  32. }

匿名组合结构体

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. type Addr struct {
  7. province string
  8. street string
  9. no string
  10. }
  11. type Tel struct {
  12. prefix string
  13. number string
  14. }
  15. // 匿名组合结构体
  16. type User struct {
  17. id int
  18. name string
  19. Addr // 只指定类型,会自动定义属性名为类型名
  20. Tel // 只指定类型
  21. birthday time.Time
  22. }
  23. func main() {
  24. // 初始化使用
  25. var user User = User{Addr: Addr{province: "guizhou"}}
  26. fmt.Printf("%T,%#v\n", user, user)
  27. fmt.Println(user.province)
  28. user.province = "广东省"
  29. fmt.Println(user.province)
  30. // 访问和修改
  31. user.Addr.province = "贵州省"
  32. fmt.Println(user.Addr.province)
  33. fmt.Println(user)
  34. }

使用实例

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. type Users struct { //值类型
  7. id int
  8. name string
  9. addr string
  10. tel string
  11. birthday time.Time
  12. created_at time.Time
  13. updated_at time.Time
  14. flag bool
  15. status int
  16. deleted_at *time.Time
  17. }
  18. func main() {
  19. // 指针
  20. var t *time.Time
  21. fmt.Println(t) // 零值nil
  22. // 定义User类型的变量
  23. var u Users // 所有属性的零值组成的一个Users类型变量值
  24. fmt.Printf("%T\n", u)
  25. fmt.Printf("%v\n", u) // 拿到结构体初始化
  26. fmt.Printf("%#v\n", u)
  27. // 赋值 按照顺序 需要给所有属性都进行赋值
  28. u = Users{1, "alinx", "贵州", "188xxxxxx", time.Now(), time.Now(), time.Now(), false, 0, nil}
  29. fmt.Printf("%#v\n", u)
  30. // 指定名称进行赋值
  31. u = Users{id: 2, name: "alinx"}
  32. fmt.Printf("%#v\n", u)
  33. // 属性访问
  34. fmt.Println(u.id)
  35. fmt.Println(u.name)
  36. fmt.Println(u.birthday.Clock())
  37. // 值类型 修改
  38. u.id = 999999
  39. fmt.Println(u.id)
  40. // 指针类型
  41. var u3 *Users
  42. fmt.Printf("%T, %v\n", u3, u3)
  43. // 指针赋值
  44. u3 = &u
  45. fmt.Println("%#v\n", u3)
  46. // new 申请空间并对元素使用0值进行初始化,取地址,赋值
  47. var u4 *Users = new(Users)
  48. var u5 *Users = &Users{} // 类似new
  49. fmt.Printf("%#v\n", u4)
  50. fmt.Printf("%#v\n", u5) // 初始化值取0值
  51. }

接口

接口是一个实现了功能的组合调用对象

  1. 接口是对行为的抽象 => 实现行为的对象
  2. 定义
  3. 接口: 定义的一些函数
  4. 签名: 参数列表,返回值列表
  5. 关键字: interface
  6. type TypeName Formatter
  7. type interfaceName interface {
  8. 方法签名
  9. }

接口使用实例

  1. package main
  2. import "fmt"
  3. // 接口定义
  4. type User struct {
  5. Id int
  6. Name string
  7. }
  8. // 定义接口 Persistent
  9. /* 行为:
  10. Save保存
  11. User切片
  12. */
  13. type Persistent interface {
  14. // 方法名称 返回值类型 接口中所定义的方法,需要有确切的实现,否则异常
  15. Save([]User,string) error
  16. Load(string) ([]User,error)
  17. }
  18. // 实现原则: 定义了GObPersustent 所有接口 就叫GObPersustent实现了Persistent接口
  19. // 第一个结构体实现 Persistent接口
  20. type GObPersustent struct {}
  21. // 基于GObPersustent结构体 实现Save方法
  22. func (p GObPersustent) Save(users []User,path string) error {
  23. fmt.Printf("\ngob persistent save")
  24. return nil
  25. }
  26. // 基于GObPersustent结构体 实现Load方法
  27. func (p GObPersustent) Load(path string) ([]User,error) {
  28. fmt.Printf("\ngob persistent load")
  29. return nil,nil
  30. }
  31. // 第二个结构体实现 Persistent接口
  32. type CsvPersistent struct{}
  33. // 基于CsvPersistent结构体 实现Save方法
  34. func (p CsvPersistent) Save(users []User,path string) error {
  35. fmt.Println("csv persistent save")
  36. return nil
  37. }
  38. // 基于CsvPersistent结构体 实现Load方法
  39. func (p CsvPersistent) Load(path string) ([]User, error) {
  40. fmt.Println("csv persistent load")
  41. return nil,nil
  42. }
  43. // 此处使用接口作为类型 对接起来调用测试
  44. func call(persistent Persistent) {
  45. fmt.Println("\ncall:")
  46. persistent.Save(nil,"")
  47. persistent.Load(":")
  48. }
  49. // 调用CsvPersistent结构体实现了 Persistent 接口的方法
  50. func Csv() {
  51. var persistent Persistent
  52. fmt.Printf("%T,%#v\n", persistent, persistent)
  53. persistent = CsvPersistent{}
  54. persistent.Load("")
  55. persistent.Save(nil,"")
  56. /*
  57. 接口 不能直接通过接口类型进行初始化对象
  58. 结构体使用实现行为(实现接口的所有方法,某个对象的类型定义了接口中所有的方法)的对象
  59. */
  60. }
  61. // 调用GObPersustent结构体实现了 Persistent 接口的方法
  62. func GOb() {
  63. var persistent Persistent
  64. fmt.Printf("%T,%#v\n", persistent, persistent)
  65. persistent = GObPersustent{}
  66. persistent.Load("")
  67. persistent.Save(nil,"")
  68. /*
  69. 接口 不能直接通过接口类型进行初始化对象
  70. 结构体使用实现行为(实现接口的所有方法,某个对象的类型定义了接口中所有的方法)的对象
  71. */
  72. }
  73. func main() {
  74. // 调用 默认是值类型调用
  75. Csv()
  76. GOb()
  77. /*
  78. 接口 不能直接通过接口类型进行初始化对象
  79. */
  80. // 在类型上 值类型会自动 生成指针类型 指针接收者无法生成值接收者
  81. var persistent Persistent
  82. fmt.Printf("%T,%#v\n", persistent, persistent)
  83. call(GObPersustent{})
  84. call(CsvPersistent{})
  85. /*
  86. 定义类型与接口是否实现 无语法上直接关联
  87. 鸭子类型: 你怎么判断一个动物是否是一个鸭子
  88. 根据行为判断: 游泳,嘎嘎叫 都是鸭子
  89. 总结: 根据以上知识 只要结构体实现了接口中定义的方法 那就是接口类型,就能赋值进行调用
  90. */
  91. // 指针对象 自动生成的指针类型调用
  92. persistent = new(CsvPersistent)
  93. fmt.Println("指针类型:\n\n%T,%#v\n", persistent,persistent)
  94. persistent.Load("")
  95. persistent.Save(nil,"")
  96. call(&CsvPersistent{})
  97. call(&GObPersustent{})
  98. }