呓语 | 杨英明的个人博客

专注于c++、Python,欢迎交流

By

Golang 间接实现 interface的一种方式

在看 k8s HPA 的时候,发现一段有意思的代码

有个接口定义为:

// kubernetes/pkg/controller/podautoscaler/metrics/interfaces.go:39
type MetricsClient interface {
    GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error)
    GetRawMetric(metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (PodMetricsInfo, time.Time, error)
    GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (int64, time.Time, error)
    GetExternalMetric(metricName string, namespace string, selector labels.Selector) ([]int64, time.Time, error)
}

也就是说某个结构体要实现以上四个方法才算实现了接口 MetricsClient,那么请看下面这个结构体 restMetricsClient 是否实现了这个接口?

// kubernetes/pkg/controller/podautoscaler/metrics/rest_metrics_client.go:51
type restMetricsClient struct {
    *resourceMetricsClient
    *customMetricsClient
    *externalMetricsClient
}
type resourceMetricsClient struct {
    client resourceclient.PodMetricsesGetter
}
func (c *resourceMetricsClient) GetResourceMetric(resource v1.ResourceName, namespace string, selector labels.Selector) (PodMetricsInfo, time.Time, error) {
    ......
}
type customMetricsClient struct {
    client customclient.CustomMetricsClient
}
func (c *customMetricsClient) GetRawMetric(metricName string, namespace string, selector labels.Selector, metricSelector labels.Selector) (PodMetricsInfo, time.Time, error) {
    ......
}
func (c *customMetricsClient) GetObjectMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (int64, time.Time, error) {
    ......
}
type externalMetricsClient struct {
    client externalclient.ExternalMetricsClient
}
func (c *externalMetricsClient) GetExternalMetric(metricName, namespace string, selector labels.Selector) ([]int64, time.Time, error) {
    ......
}

也就是说结构体 restMetricsClient 中嵌入了三个结构体,每个结构体分别实现了接口 MetricsClient 中不同的方法,最后合起来实现了接口 MetricsClient 的全部方法。

这种方式其实是结构体 restMetricsClient 间接实现了接口 MetricsClient,是有效的。

这种写法很有意思,记录一下。

原创声明

转载请注明:呓语 » Golang 间接实现 interface的一种方式