一段Golang代码引发的思考

afandaafandaafanda · · 920 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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关键字。








有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:afandaafandaafanda

查看原文:一段Golang代码引发的思考

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

920 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传