接口型函数
在 Go 语言中,函数也可以作为接口的一部分,这种称为函数接口(Function Interface)的概念让我们可以更加灵活地定义接口和实现。
通过函数接口,我们可以将函数作为接口的方法,这样就可以将不同的函数赋值给接口变量,并通过接口变量来调用这些函数。这种方式类似于将函数当作一种行为或特性来对待,使得我们可以更加方便地实现多态性和组合性。
使用函数接口,我们可以定义一个接口,然后让不同的函数去实现这个接口,从而实现统一的调用方式。这种方式非常适合于需要根据不同情况动态选择具体实现的场景,让代码更加灵活、可扩展和易于维护。
总的来说,函数接口是 Go 语言中一种非常有用的特性,它让我们可以将函数作为一种行为来对待,更加灵活地定义接口和实现,从而实现代码的解耦和灵活性。
1、例子
1
2
3
4
5
6
7
8
9
10
11
12
| // A Getter loads data for a key.
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)
}
|
2、为什么这么设计
一般有接口参与的设计会增加使用的通用性。
我们想象这么一个使用场景,GetFromSource 的作用是从某数据源获取结果,接口类型 Getter 是其中一个参数,代表某数据源。
1
2
3
4
5
6
7
| func GetFromSource(getter Getter, key string) []byte {
buf, err := getter.Get(key)
if err == nil {
return buf
}
return nil
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| //匿名
GetFromSource(GetterFunc(func(key string) ([]byte, error) {
return []byte(key), nil
}), "hello")
// 普通
func test(key string) ([]byte, error) {
return []byte(key), nil
}
func main() {
GetFromSource(GetterFunc(test), "hello")
}
|
- 方式二:实现了 Getter 接口的结构体作为参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| type DB struct{ url string}
func (db *DB) Query(sql string, args ...string) string {
// ...
return "hello"
}
func (db *DB) Get(key string) ([]byte, error) {
// ...
v := db.Query("SELECT NAME FROM TABLE WHEN NAME= ?", key)
return []byte(v), nil
}
func main() {
GetFromSource(new(DB), "hello")
}
|