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關鍵字。