• Golang 接口interface


    接口interface

    • 接口是一个或多个方法签名的集合
    • 只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这成为Structural Typing
    • 接口只有方法声明,没有实现,没有数据字段
    • 接口可以匿名嵌入其它接口,或嵌入到结构中
    • 将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,既无法修改复制品的状态,也无法获取指针
    • 只有当接口存储的类型和对象都为nil时,接口才等于nil
    • 接口调用不会做receiver的自动转换
    • 接口同样支持匿名字段方法
    • 接口也可实现类似OOP中的多态
    • 空接口可以作为任何类型数据的容器
    package main
    
    import (
    	"fmt"
    )
    
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	//连接的方法
    	Connect()
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	var a USB                            //声明一个变量,它的类型是USB接口
    	a = PhoneConnecter{"PhoneConnecter"} //这里的a是usb类型的,它无法取到name 这个字段
    	a.Connect()
    }
    
    
    package main
    
    import (
    	"fmt"
    )
    
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	//连接的方法
    	Connect()
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	// var a USB                            //声明一个变量,它的类型是USB接口
    	a := PhoneConnecter{"PhoneConnecter"} //这里的a是usb类型的,它无法去到name 这个字段
    	a.Connect()
    	Disconnect(a) //这里我们将a传进去,会发现a就是USB类型的
    }
    func Disconnect(usb USB) { // 这里传进去的要求,类型必须是USB的这个接口
    	fmt.Println("Disconnected.")
    }
    
    

    嵌入接口

    package main
    
    import (
    	"fmt"
    )
    
    type Connecter interface {
    	Connect()
    }
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	Connecter //这里将connecter的接口嵌入到USB当中
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	// var a USB                            //声明一个变量,它的类型是USB接口
    	a := PhoneConnecter{"PhoneConnecter"} //这里的a是usb类型的,它无法去到name 这个字段
    	a.Connect()
    	Disconnect(a) //这里我们将a传进去,会发现a就是USB类型的,所以可以验证PhoneConnecter实现USB的接口
    }
    func Disconnect(usb USB) { // 这里传进去的要求,类型必须是USB的这个接口
    	fmt.Println("Disconnected.")
    }
    
    

    通过类型断言的ok pattern可以判断接口中的数据类型

    package main
    
    import (
    	"fmt"
    )
    
    type Connecter interface {
    	Connect()
    }
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	Connecter
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	// var a USB                            //声明一个变量,它的类型是USB接口
    	a := PhoneConnecter{"PhoneConnecter"} //这里的a是usb类型的,它无法去到name 这个字段
    	a.Connect()
    	Disconnect(a) //这里我们将a传进去,会发现a就是USB类型的,所以可以验证PhoneConnecter实现USB的接口
    }
    func Disconnect(usb USB) { // 这里传进去的要求,类型必须是USB的这个接口
    	if pc, ok := usb.(PhoneConnecter); ok {
    		fmt.Println("Disconnected.", pc.name)
    		return
    	}
    	fmt.Println("Unknow device.")
    
    }
    //go语言当中任何类型都实现了空接口
    

    go语言当中任何类型都实现了空接口

    package main
    
    import (
    	"fmt"
    )
    
    type Connecter interface {
    	Connect()
    }
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	Connecter
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	// var a USB                            //声明一个变量,它的类型是USB接口
    	a := PhoneConnecter{"PhoneConnecter"} //这里的a是usb类型的,它无法去到name 这个字段
    	a.Connect()
    	Disconnect(a) //这里我们将a传进去,会发现a就是USB类型的,所以可以验证PhoneConnecter实现USB的接口
    }
    func Disconnect(usb interface{}) { // 这里把USB替换成空接口
    	if pc, ok := usb.(PhoneConnecter); ok {
    		fmt.Println("Disconnected.", pc.name)
    		return
    	}
    	fmt.Println("Unknow device.")
    
    }
    
    

    使用type switch则可针对空接口进行比较全面的类型判断

    package main
    
    import (
    	"fmt"
    )
    
    type Connecter interface {
    	Connect()
    }
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	Connecter
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	// var a USB                            //声明一个变量,它的类型是USB接口
    	a := PhoneConnecter{"PhoneConnecter"} //这里的a是usb类型的,它无法去到name 这个字段
    	a.Connect()
    	Disconnect(a) //这里我们将a传进去,会发现a就是USB类型的,所以可以验证PhoneConnecter实现USB的接口
    }
    func Disconnect(usb interface{}) { // 这里把USB替换成空接口
    	switch v := usb.(type) {
    	case PhoneConnecter:
    		fmt.Println("Disconnected.", v.name)
    	default:
    		fmt.Println("Unknow device.")
    	}
    
    }
    

    接口的相互转换

    package main
    
    import (
    	"fmt"
    )
    
    type Connecter interface {
    	Connect()
    }
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	Connecter
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	pc := PhoneConnecter{"PhoneConnecter"}
    	var a Connecter
    	a = Connecter(pc) //这里的a是强制类型转换,将pc转换成了Connecter接口
    	a.Connect()       //这里可以看到接口的转换,只能由超级转换成子集
    }
    //可以将拥有超集的接口转换为子集的接口
    func Disconnect(usb interface{}) { // 这里把USB替换成空接口
    	switch v := usb.(type) {
    	case PhoneConnecter:
    		fmt.Println("Disconnected.", v.name)
    	default:
    		fmt.Println("Unknow device.")
    	}
    
    }
    

    将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个
    复制品的指针,既无法修改复制品的状态,也无法获取指针

    package main
    
    import (
    	"fmt"
    )
    
    type Connecter interface {
    	Connect()
    }
    type USB interface { //定义一个接口,这个接口下面包含两个方法
    	//Name方法返回一个字符串
    	Name() string
    	Connecter
    }
    
    type PhoneConnecter struct { //用这个struct对这个USB的接口进行实现
    	name string
    }
    
    func (pc PhoneConnecter) Name() string { //实现接口就是用这个结构,实现interface的方法
    	return pc.name
    }
    func (pc PhoneConnecter) Connect() {
    	fmt.Println("Connect:", pc.name)
    }
    func main() {
    	pc := PhoneConnecter{"PhoneConnecter"}
    	var a Connecter
    	a = Connecter(pc)
    	a.Connect()
    	pc.name = "pc"       //这里将对象赋值给接口时,会发生拷贝,接口内部存储的是指向这个复制品的指针,
    	fmt.Println(pc.name) //既无法修改复制品的状态,也无法获取指针
    	a.Connect()
    }
    func Disconnect(usb interface{}) { // 这里把USB替换成空接口
    	switch v := usb.(type) {
    	case PhoneConnecter:
    		fmt.Println("Disconnected.", v.name)
    	default:
    		fmt.Println("Unknow device.")
    	}
    
    }
    
    
  • 相关阅读:
    SQL创建索引
    SQLServer最耗资源时间的SQL语句
    C# Linq删除父级的同时删除子级
    C# 根据类名创建类的实例对象
    C#利用反射实现两个类的对象之间相同属性的值的复制
    linq时间筛选以及list时间筛选
    为什么watch机制不是银弹?
    我们的前端模版引擎更新总结
    小矮人Javascript模块加载器
    Javascript模版引擎简介
  • 原文地址:https://www.cnblogs.com/skymyyang/p/7685194.html
Copyright © 2020-2023  润新知