前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang之旅19_接口interface

Golang之旅19_接口interface

作者头像
皮大大
发布2021-03-02 14:59:02
4340
发布2021-03-02 14:59:02
举报
文章被收录于专栏:机器学习/数据可视化

在Go语言中接口interface是一种类型,一种抽象的类型。

  • 如何定义接口interface
  • 接口如何实现和使用
  • 值接收者和指针接收者的区别
    • 值接收者实现接口:类型的值和类型的指针接收者都可以保存在类型变量中
    • 指针接收者实现接口:只能是指针接收者
  • 空接口的应用
  • 空接口的类型断言x.(type)

接口定义

Go语言提倡面向接口编程,每个接口由数个方法组成,接口的格式如下:

代码语言:javascript
复制
type interfaceName interface{
    方法名1( 参数列表1 ) 返回值列表1
    方法名2( 参数列表2 ) 返回值列表2
    …
}
  • 接口名:使用type关键字将接口定义为自定义的类型名。
    • 接口名字一般是er结尾
    • 接口名字最好能够体现该接口的含义,比如写操作的接口Writer,字符串功能的接口Stringer
  • 方法名:只要当方法名和接口类型名字是大写的时候,接口所在的包之外的代码能够进行访问。 记住:在go语言中首字母带包的类型才能够被外部访问
  • 参数和返回值列表:可以省略不写
代码语言:javascript
复制
// 栗子
type writer interface{
    Write([]byte) error
}

接口实现

下面的栗子中dog、cat 、person都实现了say()方法,因此在接口sayer中只要是实现了say()方法的都可以使用。

代码语言:javascript
复制
package main

import "fmt"

// 接口

type dog struct {}

// 实现方法say()
func (d dog) say(){
	fmt.Println("wangwangwang")
}

type cat struct {}

// 实现方法say()
func (c cat) say(){
	fmt.Println("miaomiaomiao")
}

type person struct {
	name string
}

// 实现方法say()
func (p person) say(){
	fmt.Println("aaaa")
}

// 实现接口,关键字interface
// 定义一个抽象的类型,只要实现say()方法,都可以传入接口中,当做sayer类型
type sayer interface {
	say()
}

// da 函数,执行接口sayer中的方法say方法
func da(arg sayer) {
	arg.say()

}

func main(){
	//c1 := cat{} //实例化
	//da(c1)
	//d1 := dog{}
	//da(d1)
	//p1 := person{
	//	name:"xiaoming",
	//}
	//da(p1)

	// 声明sayer接口类型的变量s
	var s sayer
	c2 := cat{}
	s = c2   // 实例化的结果来赋值给s
	p2 := person{name:"xiaowangzi"}
	s = p2
	fmt.Println(s)
}

值接收者和指针接收者

代码语言:javascript
复制
package main
 
import "fmt"

type mover interface{
    move()
}

type person struct {
    name string 
    age int
}

// 使用值接收者实现接口:类型的值和类型的指针接收者都可以保存在类型变量中
//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类型的值
        name: "小王子",
        age: 18,   // 逗号不能忘记
    }
    p2 := &person{
        name: "哪吒",
        age: 18,
    }
    //m = p1   使用指针接收者报错:p1是person类型的值
    m = p2
    m.move()
    fmt.Println(m)
}

类型和接口的关系

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

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

代码语言:javascript
复制
package main

import "fmt"

// 接口的嵌套:直接使用接口的名字;或者使用接口实现的方法名字
type animal interface {
    mover  
    sayer
    //move()
    //say()
    
}

type mover interface{
    move()
}

type sayer {
    say()
}

type person struct {
    name string 
    age int
}

func (p *person) move(){
    fmt.Printf("%s在跑...\n", p.name)
}

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

func main(){
    var m mover   // 定义mover类型的变量
    //p1 := person{
    //    name: "小王子",
    //    age: 18,
    //}
    p2 := &person{
        name: "哪吒", 
        age: 20,
    }
    m = p2
    m.move()
    fmt.Println(m)
    
    var s sayer   // 定义一个sayer类型的变量
    s = p2
    s.say()
    fmt.Println(s)
    
    var g  animal  // 定义animal类型的变量
    g = p2
    g.move()
    g.say()
    fmt.Println(a)
}

空接口

空接口是指没有定义任何方法的接口,任何类型都可以实现空接口。

  • 空接口类型的变量可以存储任意类型的变量
  • 空接口实现接收任意类型的函数参数
  • 空接口一般是不需要提前定义,使用的时候直接定义
代码语言:javascript
复制
package main

import "fmt"

// 空接口:接口中没有定义任何需要实现的方法
// 空接口变量可以存储任意值
// 空接口可以作为map的value;可以当做函数的参数

// 一般是不需要提前定义
type do interface {

}

func main(){
	var x interface{}   // 定义一个空接口
    
	x = "hello"  // 存储多种类型的值
	fmt.Println(x)
	x = 100
	fmt.Println(x)
	
    // 空接口作为map的值value
	var m = make(map[string] interface{}, 16)
	m["name"] = "xiaoming"
	m["age"] = 18
	m["hobby"] = []string{"篮球", "足球"}  // 切片类型
	fmt.Println(m)
}

接口值

接口值是由一个具体类型具体类型的值两部分组成,分别对应为接口的动态类型动态类型的值

如何判断空接口中类型的值:使用接口断言

代码语言:javascript
复制
x.(T)
  • x:表示类型为interface{}的变量
  • T:表示可能的类型

返回的结果中有两个值:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-10-7,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口定义
  • 接口实现
  • 值接收者和指针接收者
  • 类型和接口的关系
  • 空接口
  • 接口值
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档