Scheme机制解读(三)-Cloner-v1.5.2
什么是Cloner
Cloner是Kubernetes用来管理type对应的拷贝函数,自定义拷贝函数需要注册到Cloner中。Cloner定义在/pkg/conversion/cloner.go中:
|
|
Cloner结构体只有deepCopyFuncs和generatedDeepCopyFuncs两个字段:
- deepCopyFuncs: 管理普通拷贝函数,通过RegisterDeepCopyFunc()方法注册;
- generatedDeepCopyFuncs: 管理自动生成的拷贝函数,通过RegisterGeneratedDeepCopyFunc()方法注册。
Cloner通过NewCloner()函数生成:
|
|
和Converter一样,我们分为注册方法和拷贝方法两个类别对Cloner的方法进行介绍。
注册方法
RegisterDeepCopyFunc()
RegisterDeepCopyFunc()可以把deepCopyFunc注册到Cloner的deepCopyFuncs中。deepCpyFuncs维持有类型和拷贝函数的map关系。
|
|
RegisterGeneratedDeepCopyFunc()
RegisterGeneratedDeepCopyFunc()可以把GeneratedDeepCopyFunc注册到generatedDeepCopyFuncs中。generatedDeepCopyFuncs维持有类型和拷贝函数的关系。
|
|
拷贝方法
DeepCopy()
DeepCopy()为Cloner执行拷贝操作的入口,主要调用了deepCopy()方法。
|
|
deepCopy()
deepCopy()的流程如下:
- 获取待拷贝结构体值的类型;
- 尝试使用deepCopyFuncs中的拷贝函数进行拷贝;
- 尝试使用generatedDeepCopyFuncs中的拷贝函数进行拷贝;
- 使用defaultDeepCopy()方法。12345678910111213141516171819202122232425262728293031323334353637func (c *Cloner) deepCopy(src reflect.Value) (reflect.Value, error) {inType := src.Type()switch src.Kind() {case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:if src.IsNil() {return src, nil}}//***从deepCopyFuncs中获取拷贝函数***//if fv, ok := c.deepCopyFuncs[inType]; ok {return c.customDeepCopy(src, fv)}//***从generatedDeepCopyFuncs中获取拷贝函数***//if fv, ok := c.generatedDeepCopyFuncs[inType]; ok {var outValue reflect.ValueoutValue = reflect.New(inType.Elem())err := fv(src.Interface(), outValue.Interface(), c)return outValue, err}//***使用defaultDeepCopy()***//return c.defaultDeepCopy(src)}func (c *Cloner) customDeepCopy(src, fv reflect.Value) (reflect.Value, error) {outValue := reflect.New(src.Type().Elem())args := []reflect.Value{src, outValue, reflect.ValueOf(c)}//***执行函数***//result := fv.Call(args)[0].Interface()// This convolution is necessary because nil interfaces won't convert// to error.if result == nil {return outValue, nil}return outValue, result.(error)}
defaultDeepCopy()
defaultDeepCopy()会根据待拷贝类型的不同采取不同的拷贝方法,这过程中可能是递归拷贝。
|
|
Demo
该Demo很简单,把结构体A的值aVal拷贝成copyVal。
|
|
结果:
|
|