深入理解 Go 语言中的接口(interface)

深入理解 Go 语言中的接口(interface)

码农世界 2024-05-29 后端 69 次浏览 0个评论

一、GoLang 接口的定义

1、GoLang 中的接口
  • 在 Go 语言中接口(interface)是一种类型,一种抽象的类型
  • 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节
  • 实现接口的条件
    • 一个对象只要全部实现了接口中的方法,那么就实现了这个接口
    • 换句话说,接口就是一个需要实现的方法列表
    2、定义一个 Usber 接口
    • 定义了一个 Usber 接口让 Phone 和 Camera 结构体实现这个接口
      package main
      import "fmt"
      //1、接口是一个规范
      type Usber interface {
          start()
          stop()
      }
      //2.如果接口里面有方法的话,必要通过结构体或通过自定义类型实现这个接口
      type Phone struct{
          Name string
      }
      //3.手机摇实现 usb 接口的话必须先实现 usb 接口中的所有方法
      func (p Phone) start() {
          fmt.PrintIn(p.Name,"启动")
      }
      func (p Phone) stop() {
          fmt.PrintfIn(p.Name,"关机")
      }
      func main() {
          p := Phone{
              Name : "华为手机"
          }
          var p1 Usber    //golang中几口就是一个数据类型
          p1 = p
          p1.start()
          p1.stop()
      }
      /*
      华为手机 启动
      华为手机 关机
       */

      二、空接口

      1、空接口说明
      • golang 中空接口也可以之间当做类型来使用,可以表示任意类型
      • Golang 中的接口可以不定义任何方法,没有定义任何方法的接口就是空接口
      • 空接口表示没有任何约束,因此任何类型变量都可以实现空接口
      • 空接口在实际项目中用的是非常多的,用空接口可以表示任意类型数据
        2、空接口作为函数的参数
        package main
        import "fmt"
        //空接口作为函数的参数
        func show (a interface{}){
            fmt.Printf("值:%v,类型:%T\n",a,a)
        }
        func main(){
            show(20)        //值:20,类型:int
            show("你好 golang")    //值:您好 golang 类型:string
            slice := []int{1,2,34,5}
            show(slice)        //值:[1 2 34 5] 类型:[]int
        }
        3、切片实现空接口
        package main
        import "fmt"
        func main() {
            var slice = []interface{}{"Snail",20,true,32.2}
            fmt.PrintIn(slice)    //[Snail 20 true 32.2]
        }
        4、map 的值实现空接口 
        package main
        import "fmt"
        func main() {
            //空接口作为 map 值
            var studentInfo = make(map[string]interface{})
            studentInfo["name"] = "Snail"
            studentInfo["age"] = 18
            studentInfo["married"] = false
            fmt.PrintIn(studentInfo)
            // [age:18 married:false name:Snail]
        }

        三、类型断言

        • 一个接口的值(简称接口值)是由一个具体类型和具体类型的值两部分组成的
        • 这两部分分别称为接口的动态类型和动态值
        • 如果我们想要判断空接口中值的类型,那么这个时候就可以使用类型断言
        • 其语法格式:x.(T)
          • x:表示类型为 interface{}的变量
          • T:表示断言x 可能是的类型
          package main
          import "fmt"
          func main() {
              var x interface {}
              x = "hello golang"
              v,ok :=x.(string)
              if ok {
                  fmt.PrintIn(v)
              }else {
                  fmt.PrintIn("非字符串类型")
              }
          }

          四、值接收者和指针接收者

          1、值接收者
          • 如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量
            package main
            import "fmt"
            type Usb interface {
                Start()
                Stop()
            }
            type Phone struct {
                Name string
            }
            func (p Phone) Start() {
                fmt.PrintIn(p.Name,"开始工作")
            }
            func (p Phone) Stop() {
                fmt.Println("phone 停止")
            }
            func main() {
                phone1 := Phone{
                    Name:"华为手机"
                }
                var p1 Usb = phone1     //phone1 实现了 Usb接口 phone1 是 Phone 类型
                p1.Start()
                phone2 := &Phone{    //华为手机开始工作
                    Name:"苹果手机"
                }
                var p2 Usb = phone2      //phone2 实现了 Usb 接口 phone2 是 *Phone 类型
            	p2.Start() 
            }
            
            2、指针接收者
            • 如果结构体中的方法是指针接收者,那么实例化后结构体指针类型都可以赋值给接口变量,结构体值类型没法赋值给接口变量
              package main
              import "fmt"
              type Usb interface {
              	Start()
              	Stop()
              }
              type Phone struct {
              	Name string
              }
              func (p *Phone) Start() {
              	fmt.Println(p.Name, "开始工作")
              }
              func (p *Phone) Stop() {
              	fmt.Println("phone 停止")
              }
              func main() {
              	/*错误写法
              	phone1 := Phone{
              		Name: "小米手机",
              	}
              	var p1 Usb = phone1
              	p1.Start()
              	*/
              	//正确写法
              	phone2 := &Phone{
              		Name: "苹果手机",
              	}
              	var p2 Usb = phone2 //phone2 实现了 Usb 接口 phone2 是 *Phone 类型
              	p2.Start()
              	//苹果手机 开始工作
              }

              五、一个结构体实现多个接口

              • Golang 中一个结构体也可以实现多个接口
                package  main
                import "fmt"
                type AInterface interface {
                    GetInfo() string
                }
                type Binterface interface {
                    SetInfo(string,int)
                }
                type People struct{
                    Name string
                    Age int
                }
                func (p People) GetInfo() string(){
                    return fmt.Sprintf("姓名:%v 年龄:%d",p.Name,p.Age)
                }
                func (p *People) SetInfo(name string, age int) {
                    p.Name = name
                    p.Age = age
                }
                func main() {
                    ver people =&People{
                        Name:"Snail",
                        Age: 20,
                    }
                    // people实现了 Ainterface 和 Binterface
                    var p1 AInterface = people
                    var p2 Binterface = people
                    fmt.PrintIn(p1.GetInfo())    //姓名:Snail 年龄:20
                    p2.SetInfo("pupu",21)
                    fmt.PrintIn(p1.GEtInfo)      //姓名:pupu  年龄:21
                }

                六、接口嵌套

                • 接口与接口间可以通过嵌套创造出新的接口
                  package main 
                  import "fmt"
                  type SayInterface interface {
                      say()
                  }
                  type MoveInterface interface {
                      move()
                  }
                  //接口嵌套
                  type Animal interface {
                      SayInterface
                      MoveInterface
                  }
                  type Cat struct {
                      name string
                  }
                  func (c Cat) say() {
                      fmt.PrintIn("喵喵喵")
                  }
                  func (c Cat) move(){
                      fmt.PrintIn("猫会动")
                  }
                  func main() {
                  	var x Animal
                  	x = Cat{name: "花花"}
                  	x.move()    // 猫会动
                  	x.say()     // 喵喵喵
                  }

转载请注明来自码农世界,本文标题:《深入理解 Go 语言中的接口(interface)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,69人围观)参与讨论

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

Top