golang快速入门:接口

接口

在 Go 语言中,接口是一组仅包含方法名、参数、返回值的未具体实现的方法的集合。

scss 复制代码
type Animal interface {
	Sing()
	GetName() string
}

在 Go 语言中,类对接口的实现和子类对父类的继承一样,并没有提供类似 ​​implement​​ 这种关键字显式声明该类实现了哪个接口,一个类只要实现了某个接口要求的所有方法,我们就说这个类实现了该接口。

go 复制代码
type Chicken struct {
	Name string
}

func (ch *Chicken) Sing() {
	fmt.Println(ch.Name + "在打鸣")
}

func (ch *Chicken) GetName() string {
	return ch.Name
}

​Chicken​​ 结构体实现​​Animal​​​ 接口声明的所有方法,则​​Chicken​​​ 结构体就实现了​​​Animal​​ 接口。

通过组合实现接口继承

Go 语言也支持类似的「接口继承」特性,但是由于不支持 ​​extends​​ 关键字,是通过组合来完成的。

go 复制代码
type Animal interface {
    Call()
}

type Bird interface {
    A
    Fly()
}

type Chicken struct {}

func (c Chicken) Call() {
    fmt.Println("小鸡在打鸣")
}
func (c Chicken) Fly() {
    fmt.Println("小鸡会飞")
}

Chicken​​ 结构体可以只实现 ​​Call​​ 方法,也可以只实现 ​​Fly​​ 方法,也可以都不实现。如果只实现了 ​​Call​​ 方法,则 ​​Chicken​​ 实现了接口 ​​Animal​​;如果只实现了 ​​Fly​​ 方法,则既没有实现接口 ​​Animal​​ 也没有实现接口 ​​Bird​​,只有两个方法都实现了系统才会判定实现了接口 ​​Bird​​。

接口断言

Go 语言通过类型断言运算符 ​​.(type)​​ 来实现,其中 ​​type​​​ 对应的就是要断言的类型。下面,我们来看下具体的使用示例。

go 复制代码
type Animal interface {
	Sing()
	GetName() string
}
type Chicken struct {
	Name string
}

func (ch *Chicken) Sing() {
	fmt.Println(ch.Name + "在打鸣")
}

func (ch *Chicken) GetName() string {
	return ch.Name
}

type Cat struct {
	Name string
}

func (c *Cat) Sing() {
	fmt.Println(c.Name + "在唱歌")
}

func (c *Cat) GetName() string {
	return c.Name
}
scss 复制代码
func handle(a Animal) {
  if ch, ok := a.(*Chicken); ok {
      fmt.Println("ch is Chicken")
  }
	fmt.Println(ch, ok)

}

func main() {

	ch := Chicken{Name: "公鸡"}
	ca := Cat{Name: "喵咪"}
	handle(&ch)
	handle(&ca)
}

通过 ​​a.(*Chicken)​​ 这个表达式断言 ​​a​​ 是否是​​Chicken​​ 类型的实例,如果是,​​ok​​ 值为 ​​true​​,然后执行 ​​if​​ 语句块中的代码;否则 ​​ok​​ 值为 ​​false​​,不执行 ​​if​​ 语句块中的代码。

go 复制代码
	switch ser := a.(type) {
	case *Chicken:
		fmt.Println(ser)
	case *Cat:
		fmt.Println(ser)
	default:
		fmt.Println("其他")

	}

也可以通过switch语句做断言判断

空接口

在 Go 语言中,结构体与接口的实现关系是通过结构体所实现的方法在编译期推断出来的,如果我们定义一个空接口的话,那么显然所有的类都实现了这个接口,反过来,我们也可以通过空接口来指向任意类型, Go 的空接口实现简单,通过一个简单的字面量即可完成:

csharp 复制代码
interface{}

指向任意类型变量

csharp 复制代码
//基本类型
var v1 interface{} = 1 // 将 int 类型赋值给 interface{} 
var v2 interface{} = "空接口" // 将 string 类型赋值给 interface{} 
var v3 interface{} = true  // 将 bool 类型赋值给 interface{}

//复合类型
var v4 interface{} = &v2 // 将指针类型赋值给 interface{} 
var v5 interface{} = []int{1, 2, 3}  // 将切片类型赋值给 interface{} 
var v6 interface{} = struct{   // 将结构体类型赋值给 interface{}
    id int
    name string
}{1, "结构体"}

声明任意类型参数

go 复制代码
func Printf(fmt string, args ...interface{}) 
func Println(args ...interface{}) ...
func (p *pp) printArg(arg interface{}, verb rune)

总结

  1. 接口是一种抽象类型,描述了一个对象的行为和功能,没有数据字段。接口只定义一组方法,不做具体的功能实现,实现接口的类型必须实现所有这些方法。
  2. 实现接口的类型可以是任何类型,包括结构体、基本数据类型、数组、切片、映射或函数等,只要实现了接口的所有方法,那么它就实现了该接口。
  3. 接口类型的值可以保存任何实现了该接口的类型。它们可以作为参数传递,也可以作为返回值返回。
  4. 接口可以嵌套在其他接口中,也可以通过嵌套其他接口来实现接口的组合。
  5. 空接口interface{}没有任何方法,因此可以用来表示任何类型的值。
相关推荐
hlsd#20 分钟前
go mod 依赖管理
开发语言·后端·golang
陈大爷(有低保)24 分钟前
三层架构和MVC以及它们的融合
后端·mvc
亦世凡华、24 分钟前
【启程Golang之旅】从零开始构建可扩展的微服务架构
开发语言·经验分享·后端·golang
河西石头25 分钟前
一步一步从asp.net core mvc中访问asp.net core WebApi
后端·asp.net·mvc·.net core访问api·httpclient的使用
2401_8574396937 分钟前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧66638 分钟前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
阿华的代码王国1 小时前
【SpringMVC】——Cookie和Session机制
java·后端·spring·cookie·session·会话
小码编匠1 小时前
领域驱动设计(DDD)要点及C#示例
后端·c#·领域驱动设计
德育处主任Pro2 小时前
『Django』APIView基于类的用法
后端·python·django
哎呦没4 小时前
SpringBoot框架下的资产管理自动化
java·spring boot·后端