学习笔记根据 无闻 go语言基础教程 整理
interface
- 接口是一个或多个方法签名的集合
- Go 语言中所有类型都实现了空接口 (空接口是没有任何东西的接口)
- 只要某个类型拥有该接口的所有方法签名,即算实现该接口,无需显示声明实现了哪个接口,这称为Structural Typing
- 接口只有方法声明,没有实现,没有数据字段
- 接口可以匿名嵌入其他接口,或嵌入到结构中
- 将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个复制品的指针,即无法修改复制品的状态,也无法获取指针
- 只有当接口存储的类型和对象都为nil时,接口才等于nil
- 接口调用不会做receiver的自动转换
- 接口同样支持匿名字段方法
- 接口也可实现类似OOP中的多态
- 空接口可以作为任何类型数据的容器
- 通过类型断言的ok pattern 可以判断接口中的数据类型
- 使用 type switch 则可针对空接口进行比较全面的类型判断
- 可以将拥有超集的接口转换为子集的接口
- 示例代码:
package main
import (
"fmt"
)
type empty interface {
}
type USB interface {
Name() string
Connect()
Showing
}
type Showing interface {
Show()
}
type PhoneConnecter struct {
name string
}
func (pc PhoneConnecter) Name() string {
return pc.name
}
func (pc PhoneConnecter) Connect () {
fmt.Println("Connect:", pc.name)
}
func (pc PhoneConnecter) Show () {
fmt.Println("Showing:", pc.name)
}
func Disconnect(usb USB) {
if pc, ok := usb.(PhoneConnecter); ok {
fmt.Println("Disconnected.", pc.name)
return
}
fmt.Println("Unknown device.")
}
func Disconnect2(usb interface{}) {
if pc, ok := usb.(PhoneConnecter); ok {
fmt.Println("Disconnected.", pc.name)
return
}
fmt.Println("Unknown device.")
}
func Disconnect3(usb interface{}) {
switch v:= usb.(type) {
case PhoneConnecter:
fmt.Println("Disconnected.", v.name)
default:
fmt.Println("Unknown device.")
}
}
func main() {
test1()
test2()
test3()
test4()
test5()
test6()
test7()
test8()
}
func test1() {
var a USB
a = PhoneConnecter{"PhoneConnecter"}
a.Connect()
Disconnect(a)
}
func test2() {
a := PhoneConnecter{"PhoneConnecter"}
a.Connect()
Disconnect(a)
}
func test3() {
a := PhoneConnecter{"PhoneConnecter"}
a.Connect()
Disconnect2(a)
}
func test4() {
a := PhoneConnecter{"PhoneConnecter"}
a.Connect()
Disconnect3(a)
}
func test5() {
pc := PhoneConnecter{"PhoneConnecter"}
var a Showing
a = Showing(pc)
a.Show()
}
func test6() {
pc := PhoneConnecter{"PhoneConnecter"}
pc.name = "pc"
pc.Connect()
}
func test7() {
pc := PhoneConnecter{"PhoneConnecter"}
var a Showing
a = Showing(pc)
a.Show()
pc.name = "pc"
a.Show()
}
func test8() {
var a interface{}
fmt.Println(a == nil)
var p * int = nil
a = p
fmt.Println(a == nil)
}