Go接口(interface)的定义与实现
Go接口是方法签名的集合,实现者隐式满足接口。
接口定义语法
基本定义
Go
// 定义接口
type Reader interface {
Read(p []byte) (n int, err error)
}
// 多方法接口
type Writer interface {
Write(p []byte) (n int, err error)
}
// 组合接口
type ReadWriter interface {
Reader
Writer
}
空接口
Go
// 空接口:无方法约束
type Any interface{} // 或直接用 interface{}
// 任意类型都满足空接口
var a interface{} = 42
var b interface{} = "hello"
var c interface{} = struct{}{}
接口实现规则
隐式实现
Go
type Reader interface {
Read(p []byte) (int, error)
}
// 只要实现Read方法就满足Reader
// 无需显式声明implements
type MyReader struct{}
func (m MyReader) Read(p []byte) (int, error) {
return len(p), nil
}
// 直接赋值
var r Reader = MyReader{}
实现所有方法
Go
type ReadWriter interface {
Read(p []byte) (int, error)
Write(p []byte) (int, error)
}
// 必须实现所有方法
type MyRW struct{}
func (m MyRW) Read(p []byte) (int, error) { return 0, nil }
func (m MyRW) Write(p []byte) (int, error) { return 0, nil }
var rw ReadWriter = MyRW{} // 满足
接口内部结构
eface(空接口)
Go
// interface{}内部结构
type eface struct {
_type *_type // 类型信息
data unsafe.Pointer // 数据指针
}
// 示例
var i interface{} = 42
// _type → int类型信息
// data → 42数据地址
iface(有方法接口)
Go
// 有方法接口内部结构
type iface struct {
tab *itab // 接口表
data unsafe.Pointer // 数据指针
}
type itab struct {
inter *interfacetype // 接口类型
_type *_type // 实体类型
fun [1]uintptr // 方法地址
}
类型断言
基本断言
Go
var i interface{} = 42
// 断言类型
n := i.(int) // 成功返回值
fmt.Println(n)
// 断言失败panic
s := i.(string) // panic: interface conversion
安全断言
Go
var i interface{} = 42
// 带ok返回
n, ok := i.(int)
if ok {
fmt.Println("是int:", n)
}
s, ok := i.(string)
if !ok {
fmt.Println("不是string")
}
类型switch
Go
var i interface{} = "hello"
switch v := i.(type) {
case int:
fmt.Println("int:", v)
case string:
fmt.Println("string:", v)
case bool:
fmt.Println("bool:", v)
default:
fmt.Println("未知类型")
}
接口值判断nil
nil接口陷阱
Go
// 空接口为nil:_type=nil 且 data=nil
var i interface{} = nil
fmt.Println(i == nil) // true
// 包含nil指针的接口不为nil
var p *int = nil
var j interface{} = p
fmt.Println(j == nil) // false!
// j._type = *int(非nil)
// j.data = nil
正确判断
Go
func isNil(i interface{}) bool {
if i == nil {
return true
}
v := reflect.ValueOf(i)
switch v.Kind() {
case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Chan:
return v.IsNil()
}
return false
}
接口使用示例
定义与实现
Go
// 定义
type Processor interface {
Process(data string) string
}
// 实现A
type UpperProcessor struct{}
func (u UpperProcessor) Process(data string) string {
return strings.ToUpper(data)
}
// 实现B
type LowerProcessor struct{}
func (l LowerProcessor) Process(data string) string {
return strings.ToLower(data)
}
// 多态使用
func run(p Processor, data string) {
fmt.Println(p.Process(data))
}
run(UpperProcessor{}, "hello") // HELLO
run(LowerProcessor{}, "HELLO") // hello
要点总结
- 接口是方法签名集合
- 实现者隐式满足,无需声明
- 空接口interface{}无约束,任意类型满足
- 类型断言检查接口实际类型
- 使用ok形式安全断言避免panic
- type switch处理多种类型
- nil指针赋给接口后接口不等于nil
- 接口内部包含类型信息和数据指针
📝 发现内容有误?点击此处直接编辑