简介
k8s
大量使用了代码生成工具,但无奈文档很少,不太容易获得直观的认识,在此先记录总结一下deepcopy_gen
工具的用途和使用方法。
deepcopy_gen
这个工具从名字上来看就大概可以猜到它是用于生成深拷贝的代码。比如代码中定义了一个类型Foo
,那么使用这个工具就可以生成此类型的深拷贝方法。如果有大量自定义的类型,而且在使用过程中需要进行深拷贝,这个工具可以让我们可以非常多的代码。堪称神器。
实验
通过实际的代码能更加直观的了解这个工具
安装deepcopy_gen
|
|
下载demo代码
|
|
目录结构:
1 2 3 4 5 6 7 8 |
├── README.md ├── boilerplate.txt ├── deepcopy-gen ├── go.mod └── types ├── doc.go ├── generated_deepcopy.go └── types.go |
生成代码
|
|
执行此命令后会在当前目录生成github.com/lt90s/deepcopy-gen-demo/types/generated_deepcopy.go
的文件,该文件便是生成的深拷贝方法的代码文件,将此文件移入types
目录下便可。
分析
命令行分析
|
|
-v 2
指定输出内容的详细程度-h boilerplate.txt
指定所有生成的文件的头部声明内容--bounding-dirs .
指定生成目录为当前路径】-i github.com/lt90s/deepcopy-gen-demo/types
指定此package
需要进行代码生成-O generated_deepcopy
指定生成的文件名称为generated_deepcopy.go
生成内容分析:
打开types/generated_deepcopy.go
文件可以看到。FooType
类型生成了三个拷贝方法
func (in *FooType) DeepCopyInto(out *FooType)
func (in *FooType) DeepCopy() *FooType
func (in *FooType) DeepCopyBarInterface() BarInterface
但是BazType
却没有生成深拷贝方法,为啥呢?下面会进行分析。
生成规则分析
通过命令行参数-i
指定需要生成代码的package
后,工具会对属于此包的文件进行处理(注意并不包括此包目录下的子目录,比如types/sub下的文件就不会处理,因为它是github.com/lt90s/deepcopy-gen-demo/types/sub
)。有几种方式可以控制是否生成深拷贝代码
- 全局开关: 在文件中加入一行注释
// +k8s:deepcopy-gen=package
,通常在doc.go
文件中表明需要检查该package
下的所有自定义类型,默认情况下生成深拷贝方法 - 具体开关:在类型声明上加入一行注释
// +k8s:deepcopy-gen=false
或者// +k8s:deepcopy-gen=true
,前者表示此类型不需要生成深拷贝方法,后者表示需要生成。当全局开关打开时,只需要在不需要深拷贝方法的类型声明前加入// +k8s:deepcopy-gen=false
即可,这就是为什么BazType
没有生成相应的深拷贝方法。
在types/types.go
文件中,go
语言中的基本数据类型都是支持拷贝的,但是channel
和function
不支持,可以试一下将注释取消,然后再执行deepcopy-gen
。
interface
比较特殊,要让其支持深拷贝,必须在接口中声明DeepCopyInterfaceName() InterfaceName
方法,其中InterfaceName
是接口类型的名称。例如:
|
|
那么问题来了。如果有很多实现了这个接口类型,它们都需要深拷贝方法,那这个DeepCopyInterfaceName
方法怎么生成?deepcopy-gen
提供了// +k8s:deepcopy-gen:interfaces=github.com/foo/bar/pkg.InterfaceName
这个指令,将其放在实现了InterfaceName
接口的类型上面,工具就会自动生成DeepCopyInterfaceName
的方法。例如:
|
|
如果实现了多个接口。那么以,
分隔各个接口。
demo
中没有演示一个指令// +k8s:deepcopy-gen:nonpointer-interfaces=true
。可以看到。默认情况下,生成的DeepCopyInterfaceName
方法的接受者是指针类型的。当你不想要指针类型的接收者时,就可以使用此指令来达到目的。
总结
当自定义类型需要进行深拷贝时候,可以使用此工具来生成深拷贝方法。可以节省大量的重复代码,解放生产力。