1. 什么是多态
Go中的多态是通过接口来实现的,即可按照统一的接口来调用不同的实现,这时的接口变量就有不同的行为状态。
比如现在的Type-C
数据线,它就是多态的一种体现。一个数据线可以充电脑、可以充手机,Type-C
生产商已经做好了统一规范,比如支持充多少瓦的电源、支持充哪些设备等等。用代码来模拟这一场景:
package main
import "fmt"
// Type-C 接口
type TypecInterface interface {
// 充电
recharge()
}
type Phone struct {
// 手机型号
Model string
}
// 让手机 Phone 实现充电接口
func (p Phone) recharge() {
fmt.Println("正在给手机充电中...")
}
type Macbook struct {
// 电脑尺寸
Size string
}
// 让电脑 Macbook 实现充电接口
func (mac Macbook) recharge() {
fmt.Println("正在给电脑充电中...")
}
// 充电插头
type ChargingPlug struct {
}
// 利用充电插头 + type-c 数据线进行充电操作
func (plug *ChargingPlug)working(typec TypecInterface) {
typec.recharge()
}
func main() {
phone := Phone{}
mac := Macbook{}
plug := ChargingPlug{}
// 给手机充电
plug.working(phone)
// 给电脑充电
plug.working(mac)
}
2. 类型断言
由于接口不知道具体的数据类型,如果要转成具体类型,就需要使用类型断言。类似Java中的 instanceof
关键字。
package main
import "fmt"
type Point struct {
x int
y int
}
func main() {
var a interface{}
var point Point = Point{2, 3}
a = point // 空接口可以接受任意类型数据
// a的数据类型 main.Point, 值是={2 3}
fmt.Printf("a的数据类型 %T, 值是=%v\n", a, a)
}
那么在 Go 中能否直接执行👇🏻的代码呢?不能,会直接编译报错
var a interface{}
var b Point
// cannot use a (variable of type interface{}) as type Point in assignment: need type assertion
b = a
那么如何把一个接口变量,赋值给自定义类型的变量。此时要用到类型断言来解决该问题
package main
import "fmt"
func main() {
// 空接口类型变量
var x interface{}
var b string = "assert"
x = b // 空接口可以接受任意类型数据
// 类型断言
c := x.(string)
// b的数据类型 string, 值是=assert
fmt.Printf("b的数据类型 %T, 值是=%v\n", c, c)
// 类型断言检测机制
if y, result := x.(string); result {
fmt.Println("断言判断成功...", y)
} else {
fmt.Println("断言判断失败...")
}
}