接口实现 #

一、隐式实现 #

1.1 概念 #

Go的接口是隐式实现的,类型只需实现接口的所有方法即可。

1.2 示例 #

go
type Reader interface {
    Read() string
}

type File struct {
    content string
}

func (f File) Read() string {
    return f.content
}

var r Reader = File{content: "data"}  // 自动满足Reader

1.3 无需声明 #

go
// 不需要这样声明
// func (f File) implementsReader() {}

// 只需实现方法即可

二、方法集规则 #

2.1 值类型方法集 #

go
type Counter struct {
    value int
}

func (c Counter) Value() int {
    return c.value
}

type Valuer interface {
    Value() int
}

var v Valuer = Counter{}    // 正确
var v2 Valuer = &Counter{}  // 也正确

2.2 指针类型方法集 #

go
func (c *Counter) Increment() {
    c.value++
}

type Incrementer interface {
    Increment()
}

var i Incrementer = &Counter{}  // 正确
// var i Incrementer = Counter{}  // 错误

2.3 方法集规则表 #

方法接收者 T类型 *T类型
值接收者
指针接收者

三、接口满足条件 #

3.1 方法签名匹配 #

go
type Writer interface {
    Write([]byte) (int, error)
}

type FileWriter struct{}

func (f FileWriter) Write(data []byte) (int, error) {
    return len(data), nil
}

var w Writer = FileWriter{}  // 方法签名完全匹配

3.2 方法名匹配 #

go
type Reader interface {
    Read(p []byte) (n int, err error)
}

type MyReader struct{}

func (m MyReader) Read(data []byte) (int, error) {
    return 0, nil
}

var r Reader = MyReader{}  // 参数名可以不同

3.3 完整实现 #

go
type ReadWriter interface {
    Read(p []byte) (n int, err error)
    Write(p []byte) (n int, err error)
}

type File struct{}

func (f File) Read(p []byte) (n int, err error) {
    return 0, nil
}

func (f File) Write(p []byte) (n int, err error) {
    return 0, nil
}

var rw ReadWriter = File{}  // 必须实现所有方法

四、编译时检查 #

4.1 类型断言检查 #

go
var _ Reader = File{}       // 编译时检查
var _ Reader = (*File)(nil) // 指针类型检查

4.2 接口实现检查 #

go
type Reader interface {
    Read() string
}

type File struct{}

var _ Reader = (*File)(nil)  // 编译错误:*File未实现Reader

五、多接口实现 #

5.1 实现多个接口 #

go
type Reader interface {
    Read() string
}

type Writer interface {
    Write(string)
}

type File struct {
    content string
}

func (f *File) Read() string {
    return f.content
}

func (f *File) Write(s string) {
    f.content = s
}

var r Reader = &File{}
var w Writer = &File{}

5.2 接口组合实现 #

go
type ReadWriter interface {
    Reader
    Writer
}

var rw ReadWriter = &File{}

六、嵌入类型实现 #

6.1 结构体嵌入 #

go
type Reader struct{}

func (r Reader) Read() string {
    return "data"
}

type MyReader struct {
    Reader  // 嵌入Reader
}

var r Reader = MyReader{}  // MyReader继承了Read方法

6.2 方法覆盖 #

go
func (m MyReader) Read() string {
    return "my data"
}

var r Reader = MyReader{}
fmt.Println(r.Read())  // "my data"

七、接口值内部 #

7.1 接口值结构 #

go
type iface struct {
    tab  *itab          // 类型信息
    data unsafe.Pointer // 值指针
}

7.2 nil接口 vs 空值接口 #

go
var r Reader
fmt.Println(r == nil)  // true(nil接口)

var f *File
r = f
fmt.Println(r == nil)  // false(接口值不为nil,但值为nil)

7.3 安全调用 #

go
func safeRead(r Reader) {
    if r == nil {
        return
    }
    
    // 检查底层值是否为nil
    v := reflect.ValueOf(r)
    if v.Kind() == reflect.Ptr && v.IsNil() {
        return
    }
    
    r.Read()
}

八、实际应用 #

8.1 数据库驱动 #

go
type Driver interface {
    Open(name string) (Conn, error)
}

func Register(name string, driver Driver) {
    drivers[name] = driver
}

// mysql驱动实现
type MySQLDriver struct{}

func (d MySQLDriver) Open(name string) (Conn, error) {
    // ...
}

Register("mysql", MySQLDriver{})

8.2 HTTP处理器 #

go
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

type MyHandler struct{}

func (h MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello"))
}

http.Handle("/", MyHandler{})

8.3 中间件 #

go
type Middleware func(Handler) Handler

func LoggingMiddleware(next Handler) Handler {
    return HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.URL.Path)
        next.ServeHTTP(w, r)
    })
}

九、常见错误 #

9.1 方法签名不匹配 #

go
type Writer interface {
    Write([]byte) (int, error)
}

type MyWriter struct{}

func (m MyWriter) Write(data string) error {  // 签名不匹配
    return nil
}

var w Writer = MyWriter{}  // 编译错误

9.2 指针接收者问题 #

go
type Incrementer interface {
    Increment()
}

type Counter struct {
    value int
}

func (c *Counter) Increment() {
    c.value++
}

var i Incrementer = Counter{}  // 错误
var i Incrementer = &Counter{} // 正确

9.3 nil接口调用 #

go
var r Reader
r.Read()  // panic: nil pointer dereference

十、最佳实践 #

10.1 使用编译时检查 #

go
var _ Reader = (*File)(nil)

10.2 小接口 #

go
type Reader interface {
    Read(p []byte) (n int, err error)
}

10.3 接受接口 #

go
func Process(r Reader) error {
    // ...
}

十一、总结 #

接口实现要点:

规则 说明
隐式实现 无需显式声明
方法签名 必须完全匹配
方法集 注意指针接收者
完整实现 必须实现所有方法

关键点:

  1. 隐式实现:Go接口隐式实现
  2. 方法集:注意值类型和指针类型的区别
  3. 编译检查:使用var _ Interface = (*Type)(nil)
  4. nil接口:区分nil接口和值为nil的接口
  5. 多接口:一个类型可以实现多个接口

准备好学习接口组合了吗?让我们进入下一章!

最后更新:2026-03-26