一段Golang代码引发的思考
1.前言
Golang有一些异于其他语言的特性,如果对这些特性不了解,看一些代码的时候经常就会感到莫名其妙。最近在看Kubernetes的一段代码时,由于没有深刻领会Golang的接口机制导致一脑袋雾水,当真正理解了之后,不得不佩服Golang的灵活性,堪称神一般的存在。
2.分析
这段代码的部分片段如下,详细内容在Kubernets github:https://github.com/kubernetes/kubernetes/blob/master/pkg/admission/chain.go
1)chan.go
// chainAdmissionHandler is an instance of admission.Interface that performs admission control using a chain of admission handlers
type chainAdmissionHandler []Interface
// NewFromPlugins returns an admission.Interface that will enforce admission control decisions of all
// the given plugins.
func NewFromPlugins(client clientset.Interface, pluginNames []string, configFilePath string) Interface {
plugins := []Interface{}
for _, pluginName := range pluginNames {
plugin := InitPlugin(pluginName, client, configFilePath)
if plugin != nil {
plugins = append(plugins, plugin)
}
}
return chainAdmissionHandler(plugins)
}
// NewChainHandler creates a new chain handler from an array of handlers. Used for testing.
func NewChainHandler(handlers ...Interface) Interface {
return chainAdmissionHandler(handlers)
}
// Admit performs an admission control check using a chain of handlers, and returns immediately on first error
func (admissionHandler chainAdmissionHandler) Admit(a Attributes) error {
for _, handler := range admissionHandler {
if !handler.Handles(a.GetOperation()) {
continue
}
err := handler.Admit(a)
if err != nil {
return err
}
}
return nil
}
// Handles will return true if any of the handlers handles the given operation
func (admissionHandler chainAdmissionHandler) Handles(operation Operation) bool {
for _, handler := range admissionHandler {
if handler.Handles(operation) {
return true
}
}
return false
}这段代码里面包含了一个类型的定义:type chainAdmissionHandler []Interface,两个函数Admit和Handlers都是chainAdmissionHandler这个类型的函数,也就是Interface数组的接口的实现。注意:Admin和Handlers是Interface的数组的接口实现这点很重要。两个函数NewFromPlugins,NewChainHandler返回值是Interface,但是我们发现chainAdmissionHandler(plugins)得到的命名是Interface的数组。Interface的数组和Interface肯定是不同的类型啊,编译发现居然不报错。
下面我们看看Interface接口的定义:
// Interface is an abstract, pluggable interface for Admission Control decisions.
type Interface interface {
// Admit makes an admission decision based on the request attributes
Admit(a Attributes) (err error)
// Handles returns true if this admission controller can handle the given operation
// where operation can be one of CREATE, UPDATE, DELETE, or CONNECT
Handles(operation Operation) bool
}原来Interface也定义的是Admit和Handlers方法,也就是说chainAdmissionHandler实现了Interface接口。所以,返回chainAdmissionHandler并不报错。
3.总结
Golang的接口实现非常灵活,只要一个接口体或者类型实现了接口里面所有的方案就算实现了接口。所以跟Java不通,Golang没有implements关键字。