最近在写极客兔兔的GeeCache这个小项目,在里面遇到了一段不太理解的代码,

1
2
3
4
5
6
7
8
9
10
11
type Getter interface {
Get(key string) ([]byte, error)
}

// A GetterFunc implements Getter with a function.
type GetterFunc func(key string) ([]byte, error)

// Get implements Getter interface function
func (f GetterFunc) Get(key string) ([]byte, error) {
return f(key)
}

结合兔兔的讲解,写一篇博客

本质是实现多态

接口只有一个方法,为什么不直接使用GetterFunc作为参数传进参数?

1
2
func GetFromSource(fn GetterFunc, key string) []byte

这意味着它只能接受函数,而不能接受一个更复杂的类型,比如一个带有内部连接状态的数据库连接对象DB
我只能这样用

1
2
3
GetFromSource(func(key string) ([]byte, error){
return []byte("xxx"), nil
}, "hello")

而不能使用

1
2
3
4
5
type DB struct { ... }

func (db *DB) Get(key string) ([]byte, error) { ... }

GetFromSource(new(DB), "hello")

如果使用接口型函数

1
2
3
4
5
6
7
8
9
type Getter interface {
Get(key string) ([]byte, error)
}
type GetterFunc func(key string) ([]byte, error)

func (f GetterFunc) Get(key string) ([]byte, error) {
return f(key)
}

现在就可以传函数

1
2
3
GetFromSource(GetterFunc(func(key string) ([]byte, error) {
return []byte("hi"), nil
}), "hello")

传结构体

1
GetFromSource(new(DB), "hello")

传普通函数(转换为GetterFunc)

1
2
func fetch(key string) ([]byte, error) { ... }
GetFromSource(GetterFunc(fetch), "hello")