• Go语言入门心法(三): 接口



    Go语言入门心法(一): 基础语法

    Go语言入门心法(二): 结构体

    Go语言入门心法(三): 接口

    Go语言入门心法(四): 异常体系

     Go语言入门心法(五): 函数

    Go语言入门心法(六): HTTP面向客户端|服务端编程

    Go语言入门心法(七): 并发与通道

    Go语言入门心法(八): mysql驱动安装报错onnection failed

    Go语言入门心法(九): 引入三方依赖

    Go语言入门心法(十):Go语言操作MYSQL(CRUD)|事务处理

    Go语言入门心法(十一): 文件处理

     Go语言入门心法(十二): GORM映射框架

    Go语言入门心法(十三): 反射认知升维

    Go语言入门心法(十四): Go操作Redis实战

    Go语言入门心法(十五):Go微服务实战

    Go语言入门心法(十六):Go远程过程调用框架GRPC实战


    Golang操作数据文档: GORM 操作数据库指南



    一: go语言接口认知


    Go语言中接口认知升维:
        解决人生问题的自我引导法则: 复盘思维|结构化思维|金字塔思维|体系化思维|系统化思维
    面向对象编程(oop)三大特性: 封装,继承,多态
    Go语言中,可以认为接口是一种自定义的抽象数据类型,既然是数据类型,那么久可以使用接口声明变量等操作;
    它不会暴露出它所代表的内部属性的结构,它只会展示出它自己的方法,因此不能将接口类型实例化;
    根据go语言规范,单个函数的接口命名为函数名加上"er"作为后缀;例如:Writer,Reader,Formatter等。
    接口命令规范如下:
     (1)当个函数名的接口名以"er"作为后缀,接口的实现则去掉“er”字符串
     (2)go语言的接口是方法的集合,使用接口是实现模块化的重要方式;接口是用来定义行为类型的,这些被定义的行为不由接口直接实现
     (3)与其他语言不同的是,Go语言的接口没有数据字段(接口成员变量),只有定义的抽象的方法,不需要实现方法,不需要方法体
     定义接口与订阅结构体类似,定义需要使用type关键字和interface关键字
     type InterfaceName interface {
            Method()
     }

    1.1 接口实例一: 

    1. package main
    2. // Animal 定义接口
    3. type Animal interface {
    4. Named() string // 接口的方法,返回值类型为string
    5. Speak() string
    6. }
    7. type Cat struct {
    8. }
    9. type Dog struct {
    10. sleepTime string
    11. }
    12. // Named Cat实现接口Animal的Named()抽象方法
    13. func (cat *Cat) Named() string {
    14. return "Cat:named()-cat"
    15. }
    16. // Speak Cat实现接口Animal的Speak()抽象方法
    17. func (cat *Cat) Speak() string {
    18. return "Cat:speak()-cat"
    19. }
    20. // Named Dog实现了Animal接口的Named()抽象方法
    21. func (dog *Dog) Named() string {
    22. return "Dog:named()-dog"
    23. }
    24. // Speak Dog实现了Animal接口的Speak()抽象方法
    25. func (dog *Dog) Speak() string {
    26. return "Dog:speak()-dog"
    27. }
    28. // Sleeper 定义Dog结构体的方法
    29. func (dog *Dog) Sleeper(sleepTime string) {
    30. dog.sleepTime = sleepTime
    31. }
    32. func main() {
    33. println(`
    34. Go语言中接口认知升维:
    35. 解决人生问题的自我引导法则: 复盘思维|结构化思维|金字塔思维|体系化思维|系统化思维
    36. 面向对象编程(oop)三大特性: 封装,继承,多态
    37. Go语言中,可以认为接口是一种自定义的抽象数据类型,既然是数据类型,那么久可以使用接口声明变量等操作;
    38. 它不会暴露出它所代表的内部属性的结构,它只会展示出它自己的方法,因此不能将接口类型实例化;
    39. 根据go语言规范,单个函数的接口命名为函数名加上"er"作为后缀;例如:Writer,Reader,Formatter等。
    40. 接口命令规范如下:
    41. (1)当个函数名的接口名以"er"作为后缀,接口的实现则去掉“er”字符串
    42. (2)go语言的接口是方法的集合,使用接口是实现模块化的重要方式;接口是用来定义行为类型的,这些被定义的行为不由接口直接实现
    43. (3)与其他语言不同的是,Go语言的接口没有数据字段(接口成员变量),只有定义的抽象的方法,不需要实现方法,不需要方法体
    44. 定义接口与订阅结构体类似,定义需要使用type关键字和interface关键字
    45. type InterfaceName interface {
    46. Method()
    47. }
    48. `)
    49. println()
    50. println("=================================定义接口==========================")
    51. // 非指针实例化对象
    52. println("Cat类型就是Animal的一个实例")
    53. var cat = Cat{}
    54. println("Dog类型就是Animal的一个实例")
    55. var dog = Dog{}
    56. println("我的小猫咪: ", cat.Named())
    57. println("我的小猫咪: ", cat.Speak())
    58. println("我的小旺财: ", dog.Named())
    59. println("我的小旺财: ", dog.Speak())
    60. dog.Sleeper("10:50")
    61. println("我的小旺财休息时间: ", dog.sleepTime)
    62. }

    运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceAnimalGrammar_go.exe D:\program_file\go_workspace\org.jd.data\interface\OOPToInterfaceAnimalGrammar.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceAnimalGrammar_go.exe

            Go语言中接口认知升维:
                解决人生问题的自我引导法则: 复盘思维|结构化思维|金字塔思维|体系化思
    维|系统化思维
            面向对象编程(oop)三大特性: 封装,继承,多态
            Go语言中,可以认为接口是一种自定义的抽象数据类型,既然是数据类型,那么久可
    以使用接口声明变量等操作;
            它不会暴露出它所代表的内部属性的结构,它只会展示出它自己的方法,因此不能将接口类型实例化;
            根据go语言规范,单个函数的接口命名为函数名加上"er"作为后缀;例如:Writer,Reader,Formatter等。
            接口命令规范如下:
             (1)当个函数名的接口名以"er"作为后缀,接口的实现则去掉“er”字符串
             (2)go语言的接口是方法的集合,使用接口是实现模块化的重要方式;接口是用来定义行为类型的,这些被定义的行为不由接口直接实现
             (3)与其他语言不同的是,Go语言的接口没有数据字段(接口成员变量),只有定义的抽象的方法,不需要实现方法,不需要方法体
             定义接口与订阅结构体类似,定义需要使用type关键字和interface关键字
             type InterfaceName interface {
                    Method()
             }


    =================================定义接口==========================
    Cat类型就是Animal的一个实例
    Dog类型就是Animal的一个实例
    我的小猫咪:  Cat:named()-cat
    我的小猫咪:  Cat:speak()-cat
    我的小旺财:  Dog:named()-dog
    我的小旺财:  Dog:speak()-dog
    我的小旺财休息时间:  10:50

    Process finished with the exit code 0
     


     1.2 接口实例二:

    1. package main
    2. import (
    3. "errors"
    4. "fmt"
    5. )
    6. // IDatabase 定义一个数据库操作的接口
    7. type IDatabase interface {
    8. Connect() error
    9. Disconnect() error
    10. }
    11. // Mysql 实例类型MySQL数据操作
    12. type Mysql struct {
    13. DBName string
    14. isConnect bool
    15. }
    16. // Redis Redis实例类型
    17. type Redis struct {
    18. DBName string
    19. }
    20. // Connect 实现IDatabase接口的Connect方法
    21. func (mysql *Mysql) Connect() error {
    22. fmt.Println("Mysql Connect DB => " + mysql.DBName)
    23. // do Connect
    24. mysql.isConnect = true
    25. if mysql.isConnect {
    26. fmt.Println("Mysql Connect Success !")
    27. return nil
    28. } else {
    29. return errors.New("Connect failure ")
    30. }
    31. }
    32. // Disconnect 实现IDatabase接口的Disconnect方法
    33. func (mysql *Mysql) Disconnect() error {
    34. // do Disconnect
    35. fmt.Println("Mysql Disconnect Success !")
    36. return nil
    37. }
    38. // Connect 实现IDatabase接口的Connect方法
    39. func (redis *Redis) Connect() error {
    40. fmt.Println("Redis Connect DB => " + redis.DBName)
    41. fmt.Println("Redis Connect Success !")
    42. return nil
    43. }
    44. // Disconnect 实现IDatabase接口的Disconnect方法
    45. func (redis *Redis) Disconnect() error {
    46. // do Disconnect
    47. fmt.Println("Redis Disconnect Success !")
    48. return nil
    49. }
    50. func main() {
    51. var mysql = Mysql{DBName: "student"}
    52. println("开始连接")
    53. mysql.Connect()
    54. // do something
    55. fmt.Println("断开连接")
    56. mysql.Disconnect()
    57. var redis = &Redis{DBName: "student"}
    58. println("开始连接")
    59. redis.Connect()
    60. // do something
    61. fmt.Println("断开连接")
    62. redis.Disconnect()
    63. }

    运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceIDatabaseGrammar_go.exe D:\program_file\go_workspace\org.jd.data\interface\OOPToInterfaceIDatabaseGrammar.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceIDatabaseGrammar_go.exe
    开始连接
    Mysql Connect DB => student
    Mysql Connect Success !
    断开连接
    Mysql Disconnect Success !
    开始连接
    Redis Connect DB => student
    Redis Connect Success !
    断开连接
    Redis Disconnect Success !

    Process finished with the exit code 0
     

    二: 接口类型参数接收该接口实现类或者子接口类型的实参 

    使用接口作为参数来接收该接口实现类型实例对象或者该接口的子接口;
    go语言类型实例 相对于java语言的实现接口的类的角色:
     (1)将对象实例赋值给接口
     (2)将一个接口赋值为另外一个接口
     (3)当一个对象的类型是一个接口的实例时,这个对象就可以赋值给这个接口。需要注意的是,只能将对象的指针赋值给接口变量,不能将对象的值赋值给接口变量;
     否则会发送错误
    

    2.1 接口实例一

    1. package main
    2. import "fmt"
    3. /*
    4. 使用接口作为参数来接收该接口实现类型实例对象或者该接口的子接口;
    5. go语言类型实例 相对于java语言的实现接口的类的角色:
    6. (1)将对象实例赋值给接口
    7. (2)将一个接口赋值为另外一个接口
    8. (3)当一个对象的类型是一个接口的实例时,这个对象就可以赋值给这个接口。需要注意的是,只能将对象的指针赋值给接口变量,不能将对象的值赋值给接口变量;
    9. 否则会发送错误
    10. */
    11. type IDatabaser interface {
    12. ConnectDB() error
    13. DisconnectDB() error
    14. }
    15. // RedisDB 申明一个redis结构体
    16. type RedisDB struct {
    17. DBName string
    18. }
    19. // ConnectDB RedisDB实现接口IDatabaser的ConnectDB()方法
    20. func (redis *RedisDB) ConnectDB() error {
    21. fmt.Println("Redis Connect DB => " + redis.DBName)
    22. // do Connect
    23. fmt.Println("Redis Connect Success !")
    24. return nil // 返回一个错误nil,表示无错误
    25. }
    26. // DisconnectDB RedisDB实现接口IDatabaser的DisconnectDB()方法
    27. func (redis *RedisDB) DisconnectDB() error {
    28. // do Disconnect
    29. fmt.Println("Redis Disconnect Success !")
    30. return nil
    31. }
    32. func main() {
    33. // 创建一个RedisDB实例化值对象,并初始化赋值
    34. var redis = RedisDB{
    35. DBName: "person:id_", //赋值分行写时,需要添加默认的逗号; 如果写一行,则逗号可以省略,当然也可以保留
    36. }
    37. // 声明一个接口类型的变量idb;接口类型变量,是指用接口作为变量的数据类型来声明的变量;并把接口类型实现的类型RedisDB实例化对象的指针赋值给该接口
    38. var idb IDatabaser = &redis
    39. // 然后使用该接口类型变量操作接口类型实例的相关方法,完成具体的业务逻辑
    40. idb.ConnectDB()
    41. idb.DisconnectDB()
    42. }

    运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceeReceiverValue_go.exe D:\program_file\go_workspace\org.jd.data\interface\OOPToInterfaceeReceiverValue.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceeReceiverValue_go.exe
    Redis Connect DB => person:id_
    Redis Connect Success !
    Redis Disconnect Success !

    Process finished with the exit code 0
     


    2.2 接口实例二 

    1. package main
    2. import "fmt"
    3. type LinkDatabaser interface {
    4. // Connected 连接方法
    5. Connected() error
    6. // Released 释放连接
    7. Released() error
    8. }
    9. // IRediser 定义一个子接口
    10. type IRediser interface {
    11. // Connected 连接方法
    12. Connected() error
    13. }
    14. // RedisInstance 定义一个结构体
    15. type RedisInstance struct {
    16. DBName string // 结构体
    17. }
    18. // Connected 实现接口的Connected()方法
    19. func (redis *RedisInstance) Connected() error {
    20. fmt.Println("Redis Connect DB => " + redis.DBName)
    21. // do Connect
    22. fmt.Println("Redis Connect Success !")
    23. return nil
    24. }
    25. // Released 实现接口的Released方法
    26. func (redis *RedisInstance) Released() error {
    27. // do Disconnect
    28. fmt.Println("Redis Disconnect Success !")
    29. return nil
    30. }
    31. func main() {
    32. println(`
    33. 通过一个接口给另外一个接口赋值,在go语言中只要两个接口拥有统同样的方法集(次序不同不要紧)
    34. 那么它们就是相同的,可以相互赋值。如果两个接口不是相同的,接口A的方法时接口B方法集的子集,那么接口B可以赋值给接口A,反正不成立
    35. `)
    36. println()
    37. println()
    38. var idb LinkDatabaser = &RedisInstance{
    39. DBName: "teacher"}
    40. var iRedis IRediser
    41. iRedis = idb
    42. err := iRedis.Connected()
    43. if err != nil {
    44. println("redis数据库连接异常........")
    45. return
    46. }
    47. }

    运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceeReceiverSubInterfaceValue_go.exe D:\program_file\go_workspace\org.jd.data\interface\OOPToInterfaceeReceiverSubInterfaceValue.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceeReceiverSubInterfaceValue_go.exe

           通过一个接口给另外一个接口赋值,在go语言中只要两个接口拥有统同样的方法集(
    次序不同不要紧)
           那么它们就是相同的,可以相互赋值。如果两个接口不是相同的,接口A的方法时接口B方法集的子集,那么接口B可以赋值给接口A,反正不成立


    Redis Connect DB => teacher
    Redis Connect Success !

    Process finished with the exit code 0

    三: go语言中接口嵌套认知


    go语言接口嵌套认知升维
    接口嵌套也称接口组合,在其他语言如Java中,这种接口的组合叫继承;go语言中摒弃了纷繁的继承体系,go语言中这种继承体系是通过接口嵌套来体系
    接口嵌套也就是如果一个接口interface1作为interface2的一个嵌入字段,那么interface2隐式包含了interface1里面的所有的方法;
    接口嵌套分为:
       (1)接口侵入式嵌套
       (2)接口非侵入式嵌套
    接口嵌套注意事项:
       一个接口类型只能接受其他类型的接口嵌入,嵌入结构体或者其他类型都会报错;
       一个接口类不能嵌入自身,这包括直接嵌入和间接嵌入

    1. package main
    2. import "fmt"
    3. /*
    4. go语言接口嵌套认知升维
    5. 接口嵌套也称接口组合,在其他语言如Java中,这种接口的组合叫继承;go语言中摒弃了纷繁的继承体系,go语言中这种继承体系是通过接口嵌套来体系
    6. 接口嵌套也就是如果一个接口interface1作为interface2的一个嵌入字段,那么interface2隐式包含了interface1里面的所有的方法;
    7. 接口嵌套分为:
    8. (1)接口侵入式嵌套
    9. (2)接口非侵入式嵌套
    10. 接口嵌套注意事项:
    11. 一个接口类型只能接受其他类型的接口嵌入,嵌入结构体或者其他类型都会报错;
    12. 一个接口类不能嵌入自身,这包括直接嵌入和间接嵌入
    13. */
    14. type IPerson interface {
    15. Speak()
    16. }
    17. type IStudent interface {
    18. IPerson // 嵌入IPerson接口
    19. Study() // 学习活动
    20. }
    21. type ITeacher interface {
    22. IPerson
    23. Teach() // 教学活动
    24. }
    25. type Student struct {
    26. Name string
    27. }
    28. // Speak Student实现Speak方法
    29. func (student *Student) Speak() {
    30. fmt.Println("My name is", student.Name)
    31. }
    32. // Study Student实现Study方法
    33. func (student *Student) Study() {
    34. fmt.Println(student.Name, " is studying")
    35. }
    36. type Teacher struct {
    37. Name string
    38. }
    39. // Speak Teacher实现Speak方法
    40. func (teacher *Teacher) Speak() {
    41. fmt.Println("My name is", teacher.Name)
    42. }
    43. // Teach Teacher实现Study方法
    44. func (teacher *Teacher) Teach() {
    45. fmt.Println(teacher.Name, " is teaching")
    46. }
    47. func main() {
    48. println(`
    49. 从上面的声明与定义,IStudent,ITeacher接口都嵌入了IPerson,因此可以把它们看成继承了IPerson的相关方法;都拥有IPerson中的所有方法
    50. 而结构体Teacher需要实现IPerson接口,同时要实现ITeacher接口才能拥有相关的方法及属性
    51. `)
    52. var student Student = Student{"老杨"}
    53. var teacher Teacher = Teacher{
    54. "马士兵"}
    55. student.Study()
    56. student.Speak()
    57. teacher.Speak()
    58. teacher.Teach()
    59. }

    运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceNestInterface_go.exe D:\program_file\go_workspace\org.jd.data\interface\OOPToInterfaceNestInterface.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPToInterfaceNestInterface_go.exe
    老杨  is studying
    My name is 老杨
    My name is 马士兵
    马士兵  is teaching

    Process finished with the exit code 0


    四: go语言中空接口认知


    将值报错到空接口:
    
          空接口(interface{})是go语言中最特殊的接口,在Java语言中,所有的类都继承自一个基类Object;
           而go语言中的interface{}接口就相当于这里的Object;
           在go语言中,空接口不包括任何方法,也正因如此,所有的类都实现了空接口,因此空接口可以存储任意类型的数值;

    4.1 空接口实例一 

    1. package main
    2. import "fmt"
    3. /*
    4. 将值报错到空接口:
    5. 空接口(interface{})是go语言中最特殊的接口,在Java语言中,所有的类都继承自一个基类Object;
    6. 而go语言中的interface{}接口就相当于这里的Object;
    7. 在go语言中,空接口不包括任何方法,也正因如此,所有的类都实现了空接口,因此空接口可以存储任意类型的数值;
    8. */
    9. func Logg(name string, i interface{}) {
    10. // println("i类型为空接口,可以接收任意类型的类型的变量")
    11. fmt.Printf("Name = %s ,Type = %T, value = %v\n", name, i, i)
    12. }
    13. func main() {
    14. // 使用空接口声明任意变量
    15. var v1 interface{} = 1
    16. var v2 interface{} = "老杨"
    17. var v3 interface{} = true
    18. var v4 interface{} = &v1
    19. var v5 interface{} = struct { // 匿名结构体
    20. Name string
    21. }{"老板"}
    22. var v6 interface{} = &v5
    23. Logg("v1", v1)
    24. Logg("v2", v2)
    25. Logg("v3", v3)
    26. Logg("v4", v4)
    27. Logg("v5", v5)
    28. Logg("v6", v6)
    29. }

    运行效果:

    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPEmptyInterfaceToStoreValue_go.exe D:\program_file\go_workspace\org.jd.data\struct\OOPEmptyInterfaceToStoreValue.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPEmptyInterfaceToStoreValue_go.exe
    Name = v1 ,Type = int, value = 1
    Name = v2 ,Type = string, value = 老杨
    Name = v3 ,Type = bool, value = true
    Name = v4 ,Type = *interface {}, value = 0xc00008a030
    Name = v5 ,Type = struct { Name string }, value = {老板}
    Name = v6 ,Type = *interface {}, value = 0xc00008a040

    Process finished with the exit code 0
     


    4.2 空接口实例二 

    空接口中取值演示

    1. package main
    2. import "fmt"
    3. /*
    4. 既然空接口可以存储各种类型的值,那么怎么从空接口中取值呢?,接下来我们来演示取值
    5. */
    6. func main() {
    7. println("从空接口中获取对应类型的值:")
    8. var a string = "abc"
    9. // 字符串类型变量赋值给空接口类型的变量i
    10. var i interface{} = a
    11. // 空类型的变量i赋值给字符串类型b
    12. var b string = i.(string)
    13. fmt.Println(b)
    14. println("================下面来看下空接口常见使用=========================")
    15. println(`
    16. 来看下fmt模块的Println方法源代码:
    17. (1)func Println(a ...any) (n int, err error) {
    18. return Fprintln(os.Stdout, a...)
    19. }
    20. (2)// any is an alias for interface{} and is equivalent to interface{} in all ways.
    21. type any = interface{}
    22. 可以标准输出函数的参数类型是空接口: 打印函数支持传入任意个值,并且值的类型也是任意的
    23. `)
    24. println(`
    25. t,ok := X.(T)||空接口变量.(对应转换类型):
    26. 该语法称为接口的断言:
    27. `)
    28. println()
    29. println("========================下面来写空接口为参数函数一个实例Logger()======================")
    30. s := make([]interface{}, 3) // 构建一个可接收任意类型的数值,限制三个元素
    31. s[0] = 1
    32. s[1] = "abc"
    33. s[2] = struct {
    34. Num int
    35. }{1111}
    36. // 可变长度的参数
    37. fmt.Println("=====================将切分拆散===============")
    38. Logger(s...)
    39. println("=======================直接传入切片=============")
    40. Logger(s)
    41. }
    42. func Logger(args ...interface{}) {
    43. for num, arg := range args { // 遍历参数
    44. // 是用标准模块下的个数化输出打印函数
    45. fmt.Printf("Index => %d ,Value => %v\n", num, arg)
    46. }
    47. }

    运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPEmptyInterfaceToValue_go.exe D:\program_file\go_workspace\org.jd.data\struct\OOPEmptyInterfaceToValue.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPEmptyInterfaceToValue_go.exe
    从空接口中获取对应类型的值:
    abc
    ================下面来看下空接口常见使用=========================

          来看下fmt模块的Println方法源代码:
           (1)func Println(a ...any) (n int, err error) {
                 return Fprintln(os.Stdout, a...)
           }
           (2)// any is an alias for interface{} and is equivalent to interface{} in all ways.
            type any = interface{}
            可以标准输出函数的参数类型是空接口: 打印函数支持传入任意个值,并且值的类
    型也是任意的

            t,ok := X.(T)||空接口变量.(对应转换类型):
            该语法称为接口的断言:

    ========================下面来写空接口为参数函数一个实例Logger()======================
    =====================将切分拆散===============
    Index => 0 ,Value => 1
    Index => 1 ,Value => abc
    Index => 2 ,Value => {1111}
    =======================直接传入切片=============
    Index => 0 ,Value => [1 abc {1111}]

    Process finished with the exit code 0
     


    五: go语言中类型断言认知 

    类型断言是使用在"接口变量"上的操作,这里的接口变量指的是接口类型声明的变量;
    通俗来讲,就是接口类型的变量转换为普通类型的转换就是接口断言
       类型断言的语法:
          t,ok := X.(T)
          x表示接口变量,T表示一个类型(当然也可以是接口类型),这语法的意思就是判断X是否是T类型,如果断言成功,
          则ok为true,t的值为接口变量X的动态值;如果断言失败,则t的值为类型t的初始值,t的类型始终为T
    

    5.1 类型断言实例一

    1. package main
    2. import (
    3. "fmt"
    4. )
    5. /*
    6. 类型断言是使用在"接口变量"上的操作,这里的接口变量指的是接口类型声明的变量;
    7. 通俗来讲,就是接口类型的变量转换为普通类型的转换就是接口断言
    8. 类型断言的语法:
    9. t,ok := X.(T)
    10. x表示接口变量,T表示一个类型(当然也可以是接口类型),这语法的意思就是判断X是否是T类型,如果断言成功,
    11. 则ok为true,t的值为接口变量X的动态值;如果断言失败,则t的值为类型t的初始值,t的类型始终为T
    12. */
    13. func main() {
    14. var X interface{} = 1
    15. fmt.Println("第一次断言")
    16. t0, ok := X.(string)
    17. checkType(t0, ok)
    18. fmt.Println("第二次断言")
    19. t1, ok := X.(float64)
    20. checkType(t1, ok)
    21. fmt.Println("第三次断言")
    22. t2, ok := X.(int)
    23. checkType(t2, ok)
    24. }
    25. func checkType(t interface{}, ok bool) {
    26. if ok {
    27. fmt.Println("断言成功!")
    28. } else {
    29. fmt.Println("断言失败!")
    30. }
    31. fmt.Printf("变量t的类型 = %T ,值 = %v \n", t, t)
    32. }

     运行效果:


    GOROOT=D:\program_file_worker\go1.20 #gosetup
    GOPATH=D:\program_file_worker\go1.20\bin;C:\Users\Administrator\go #gosetup
    D:\program_file_worker\go1.20\bin\go.exe build -o C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPEmptyInterfaceToAssertGrammar_go.exe D:\program_file\go_workspace\org.jd.data\struct\OOPEmptyInterfaceToAssertGrammar.go #gosetup
    C:\Users\Administrator\AppData\Local\Temp\GoLand\___go_build_OOPEmptyInterfaceToAssertGrammar_go.exe
    第一次断言
    断言失败!
    变量t的类型 = string ,值 =
    第二次断言
    断言失败!
    变量t的类型 = float64 ,值 = 0
    第三次断言
    断言成功!
    变量t的类型 = int ,值 = 1

    Process finished with the exit code 0



    5.2 类型断言实例二 

     忙着去耍帅,后期补充完整。。。。。

  • 相关阅读:
    找搭建app的朋友,要求什么都会。
    踩坑记:JSON.parse和JSON.stringify
    2023 版 Java和python开发线性代数探索
    一文速学-时间序列分析算法之指数平滑法详解+Python代码实现
    c# 类的介绍及延伸
    新闻文化建设杂志新闻文化建设杂志社新闻文化建设编辑部2022年第14期目录
    电池厂提供excel电池曲线zcv到mtk电池曲线zcv转换
    SwiftUI简单基础知识学习
    5.springcloudalibaba nacos 2.2.3源码下载并且注册服务到nacos
    Flink SQL通过Hudi HMS Catalog读写Hudi并同步Hive表(强烈推荐这种方式)
  • 原文地址:https://blog.csdn.net/u014635374/article/details/133824163