接口类型

go语言中接口(interface)是一种类型,一种抽象的类型。
interface是一组method的集合,是duck-type programming的一种体现。接口做的事情就像是定义一个协议(规则),只要一台机器有洗衣服和甩干的功能,我就称它为洗衣机。不关心属性(数据),只关心行为(方法)。

空接口

空接口的定义

interface{} 类型,空接口。interface{} 类型是没有方法的接口。由于没有 implements 关键字,所以所有类型都至少实现了 0 个方法,所以 所有类型都实现了空接口。这意味着,如果编写一个函数以 interface{} 值作为参数,那么可以为该函数提供任何值。

  1. func main() {
  2. // 定义一个空接口x
  3. var x interface{}
  4. s := "Hello11"
  5. x = s
  6. fmt.Printf("type:%T value:%v\n", x, x)
  7. i := 100
  8. x = i
  9. fmt.Printf("type:%T value:%v\n", x, x)
  10. b := true
  11. x = b
  12. fmt.Printf("type:%T value:%v\n", x, x)
  13. }

空接口作为map的值

  1. package main
  2. import "fmt"
  3. //空接口
  4. type null1 interface {}
  5. //空接口可做任意类型 做map值 任意数值
  6. func main() {
  7. map1 := make(map[string]interface{},100)
  8. map1["z"] = 100
  9. map1["d"] = "ll"
  10. map1["ture"] = true
  11. fmt.Println(map1)
  12. }

类型断言

空接口可以存储任意类型的值,那我们如何获取其存储的具体数据呢?

想要判断空接口中的值这个时候就可以使用类型断言,其语法格式:
x.(T)
其中:

  • x:表示类型为interface{}的变量
  • T:表示断言x可能是的类型。

该语法返回两个参数,第一个参数是x转化为T类型后的变量,第二个值是一个布尔值,若为true则表示断言成功,为false则表示断言失败。

  1. func main() {
  2. var a interface{}
  3. a = "1111"
  4. v, ok := a.(string)
  5. if ok {
  6. fmt.Println(a)
  7. } else {
  8. fmt.Println("failed")
  9. }
  10. }

值接收者和指针接收者实现接口的区别

  1. //定义动物接口类型
  2. type animal interface {
  3. speak()
  4. move()
  5. }
  6. type cat struct {
  7. name string
  8. }
  9. //值接受者---------------------
  10. /*
  11. func (c cat) speak() {
  12. fmt.Println("miao")
  13. }
  14. func (c cat) move() {
  15. fmt.Println("move11")
  16. }
  17. func main() {
  18. var a animal
  19. var b animal
  20. ling1 := cat{"lingling"}
  21. tom := &cat{"xiaohua"} //语法糖 xiangdangyu *tom := &cat
  22. a = tom
  23. b = ling1
  24. tom.speak() // (*tom.speak())
  25. fmt.Println(a)
  26. }

使用值接收者实现接口之后,不管是cat结构体还是结构体指针cat类型的变量都可以赋值给该接口变量。因为Go语言中有对指针类型变量求值的语法糖,cat指针内部会自动求值tom。

  1. //指针接受者---------------------
  2. func (c *cat) speak() {
  3. fmt.Println("miao")
  4. }
  5. func (c *cat) move() {
  6. fmt.Println("move11")
  7. }
  8. func main() {
  9. var a animal
  10. tom := &cat{"xiaohua"} //语法糖 xiangdangyu *tom := &cat
  11. a = tom
  12. tom.speak() // (*tom.speak())
  13. a.move()
  14. }

此时实现接口的是cat类型,所以不能给a传入cat类型的tom,此时a只能存储cat类型的值。