Go接口interface

Go接口interface

接口在底层分为接口类型和接口值,零值为nil

为什么使用接口


package main

import (
   "fmt"
)
//为什么需要接口
type dog struct {
     

}

func (d dog) say()  {
     
   fmt.Print("汪汪汪~")
}

type cat struct {
     

}

func (c cat)say()  {
     
   fmt.Println("喵喵喵~")
}

//接口不管你是什么类型,他只管你要实现什么方法
//定义一个类型,一个抽象的类型,只要实现了say()这个方法的类型都可以陈革伟sayer类型
type sayer interface {
     
   say()
}

//da的函数
func da(arg  sayer)  {
     
   arg.say()//不管传进来的是什么,我都要大Ta,就要执行Ta的say方法
}

func main()  {
     
   c1:= cat{
     }
   da(c1)
   d1:=dog{
     }
   da(d1)
}

使用值接受者实现接口和使用指针接受者实现接口的区别

package main

import "fmt"

//使用值接受者实现接口和使用指针接受者实现接口的区别
type mover interface {
     
   move()
}

type person struct {
     
   name string
   age int8
}

//使用值接受者实现接口:不管是类型的值还是类型的指针都可以保存到接口变量中
//func (p person) move() {
     
// fmt.Printf("%s再跑...",p.name)
//}

//使用指针接受者实现接口:只能将类型的指针保存到接口变量中
func (p *person) move() {
     
   fmt.Printf("%s还在跑...",p.name)
}

func main()  {
     
   var m mover
   //p1 :=person{//person类型的值
   // "小王子",
   // 18,
   //}
   p2 :=&person{
     //person类型的指针
      "小公主",
      19,
   }
   //m=p1//?无法复制,因为p1是person类型的值没有实现mover接口
   m=p2
   m.move()
   fmt.Println(m)
}

一个类型可以实现多个接口

package main

import "fmt"

//路由嵌套
type all interface {
     
   mover
   sayer
}

//使用值接受者实现接口和使用指针接受者实现接口的区别
type mover interface {
     
   move()
}

type sayer interface {
     
   say()
}

type person struct {
     
   name string
   age int8
}

//使用值接受者实现接口:不管是类型的值还是类型的指针都可以保存到接口变量中
//func (p person) move() {
     
// fmt.Printf("%s再跑...",p.name)
//}

//使用指针接受者实现接口:只能将类型的指针保存到接口变量中
func (p *person) move() {
     
   fmt.Printf("%s还在跑...",p.name)
}

func (p *person) say() {
     
   fmt.Printf("%s在叫",p.name)
}

func main()  {
     
   var m mover
   //p1 :=person{//person类型的值
   // "小王子",
   // 18,
   //}
   var n sayer
   p2 :=&person{
     //person类型的指针
      "小公主",
      19,
   }
   //m=p1//?无法复制,因为p1是person类型的值没有实现mover接口
   m=p2
   n=p2
   m.move()
   fmt.Println(m)
   n.say()

   var s all
   s = p2//p2既实现了say方法,也实现了move方法因此可以将p2存入到接口中去
   s.move()
   s.say()
}

多个类型也可以实现同一个接口

package main

import (
   "fmt"
)
//为什么需要接口
type dog struct {
     

}

func (d dog) say()  {
     
   fmt.Print("汪汪汪~")
}

type cat struct {
     

}

func (c cat)say()  {
     
   fmt.Println("喵喵喵~")
}

//接口不管你是什么类型,他只管你要实现什么方法
//定义一个类型,一个抽象的类型,只要实现了say()这个方法的类型都可以陈革伟sayer类型
type sayer interface {
     
   say()
}

//da的函数
func da(arg  sayer)  {
     
   arg.say()//不管传进来的是什么,我都要大Ta,就要执行Ta的say方法
}

func main()  {
     
   c1:= cat{
     }
   da(c1)
   d1:=dog{
     }
   da(d1)
}

空接口

空接口是指没有定义的任何方法,因此任何类型都实现了空接口

空接口类型的变量可以存储任意类型的变量

import (
   "fmt"
)

//空接口
//接口中没有定义任何方法值
//任意类型都实现了空接口-->空接口变量可以存储任意值

//空接口一般不需要提前定义。用到时直接使用就可以
type xxx interface {
     }//没必要写

//空接口的应用
//1.空接口类型作为函数的参数(例如printf函数可以打印任意类型的变量,是因为prin函数在参数类型哪里是可变长度的空接口)
//func Println(a ...interface{}) (n int, err error) {
     
// return Fprintln(os.Stdout, a...)
//}
//2.空接口可以作为map的value


func main()  {
     
   var x interface{
     }//定义x为一个空接口类型的变量,这样就可以想x中存储任意类型的变量
   x= "hello"
   fmt.Println(x)
   x=100
   fmt.Println(x)
   x=true
   fmt.Println(x)

   var m = make(map[string]interface{
     },16)
   m["name"]="娜扎"
   m["age"]=18
   m["hobby"]=[]string{
     "篮球","足球","双色球"}
   fmt.Println(m)
}

接口值

一个接口的值(简称接口值)是有一个具体类型和具体类型的值两部分组成的。这两部分分别称为接口的动态类型和动态值

类型断言

package main

import (
   "fmt"
)

//空接口
//接口中没有定义任何方法值
//任意类型都实现了空接口-->空接口变量可以存储任意值

//空接口一般不需要提前定义。用到时直接使用就可以
type xxx interface {
     }//没必要写

//空接口的应用
//1.空接口类型作为函数的参数(例如printf函数可以打印任意类型的变量,是因为prin函数在参数类型哪里是可变长度的空接口)
//func Println(a ...interface{}) (n int, err error) {
     
// return Fprintln(os.Stdout, a...)
//}
//2.空接口可以作为map的value


func main()  {
     
   var x interface{
     }//定义x为一个空接口类型的变量,这样就可以想x中存储任意类型的变量
   x= "hello"//存入的值分为两步,存入类型和值
   //fmt.Println(x)
   x=100
   //fmt.Println(x)
   //fmt.Println(x)

   //var m = make(map[string]interface{},16)
   //m["name"]="娜扎"
   //m["age"]=18
   //m["hobby"]=[]string{"篮球","足球","双色球"}
   //fmt.Println(m)

   //类型断言
   ret,ok:=x.(int)//猜的类型不对时、ok=false,ret=string类型的零值
   if !ok{
     
      fmt.Println("不是字符串类型")
   }else {
     
      fmt.Println("是字符串类型")
   }
   fmt.Println(ret)


   //类型断言的另外一种写法
   switch v:= x.(type) {
     
   case string:
      fmt.Printf("字符串 %v ",v)
   case bool:
      fmt.Printf("是布尔类型%v",v)
   case int:
      fmt.Printf("是int型",v)
   default:
      fmt.Printf("智穷了,%v",v)
   }
}

你可能感兴趣的:(go,golang)