package main
import "fmt"
type A struct {
int // 相当于 int int,也就是相当于声明了一个名称为int、数据类型为int的字段
// 也就是 匿名字段的默认字段名称就是类型的名称
// int // 不能重复声明
Name string
}
func main() {
a := A{}
a.int = 10
fmt.Println(a.int) // 10
}
type 接口名 interface {
method1(参数列表) 返回值列表
method2(参数列表) 返回值列表
}
注意事项:
接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量
接口中所有的方法都没有方法体,即都是没有实现的方法
接口中不能含有任何变量或常量
在golang中,一个自定义类型需要将某个接口的所有方法都实现,我们才说这个类型实现了该接口
只要是自定义类型都是可以实现接口,不仅仅是结构体类型
一个自定义类型可以实现多个接口
一个接口可以继承多个别的接口,如果要实现接口A,那么他所继承的B以及C接口中的方法也必须实现
type A interface {
B // A接口继承B以及C接口
C
a()
}
type B interface {
b()
}
type C interface {
c()
}
如果接口继承之间含有相同的方法名,会报错(go1.7不报错)
type A interface {
B
C // 报错,含有两个相同的test方法
}
type B interface {
test()
b()
}
type C interface {
test()
c()
}
示例:
package main
import "fmt"
// Usb 定义一个接口
type Usb interface {
Start() // 给接口声明两个方法 Start 和 Stop
Stop()
}
// Phone 定义一个手机结构体,实现Usb接口的方法
type Phone struct {
}
func (p Phone) Start() {
fmt.Println("手机开始工作")
}
func (p Phone) Stop() {
fmt.Println("手机结束工作")
}
// Camera 定义一个相机结构体,实现Usb接口的方法
type Camera struct {
}
func (c Camera) Start() {
fmt.Println("相机开始工作")
}
func (c Camera) Stop() {
fmt.Println("相机结束工作")
}
// Computer 定义一个计算机
type Computer struct {
}
// Working 方法接收一个Usb接口类型的变量,并调用Usb方法中的方法
func (c Computer) Working(usb Usb) { // 这里的Usb就是多态的体现,类型上溯
usb.Start()
usb.Stop()
}
func main() {
// 在golang中,实现接口 = 定义了接口中的所有方法
var camera Usb = Camera{} // 多态
var phone Usb = Phone{}
computer := Computer{}
computer.Working(camera)
computer.Working(phone)
}
多态
package main
import "fmt"
type A interface {
sayA()
}
type B struct {
Name string
}
// B 实现 A 接口
func (b B) sayA() {
fmt.Println("你好 a")
}
func (b B) sayB() {
fmt.Println("你好 b", b.Name)
}
func main() {
// 上溯造型
var a A = B{"小熊"}
a.sayA()
// 下塑造型 (类型断言,不是类型转换,因为这个变量本身就是该类型,只是断言)
var b B = a.(B) // 将变量a转换为类型B,如果类型断言失败将会报错
b.sayB()
}
**类型断言:**由于接口是一般类型,不知道具体类型,如果需要具体类型,就需要使用类型断言
要进行类型断言的变量本身就是这个类型,不是类型强转,类型断言只是断言类型
如果类型不匹配,类型断言会抛出panic: interface conversion
所以,在进行类型断言时,一定要确定类型
类型断言之前进行检测机制:
// 下塑造型 (类型断言)
b, ok := a.(B)
if ok {
b.sayB()
} else {
fmt.Println("类型断言失败")
}
switch + 类型断言:
func TypeJudge(items ...interface{}) {
for i, item := range items {
switch item.(type) { // type 是一个关键字,代表使用case语句中的类型对item进行类型断言
case bool:
fmt.Printf("param %d is bool, value is %t", i, item)
case float32, float64:
fmt.Printf("param %d is float, value is %v", i, item)
case int8, int16, int32, int64, int:
fmt.Printf("param %d is int, value is %v", i, item)
case nil:
fmt.Printf("param %d is nil, value is %v", i, item)
case string:
fmt.Printf("param %d is string, value is %v", i, item)
}
}
}