项目作者: globusdigital

项目描述 :
Deep copy generator
高级语言: Go
项目地址: git://github.com/globusdigital/deep-copy.git
创建时间: 2020-01-07T13:16:10Z
项目社区:https://github.com/globusdigital/deep-copy

开源协议:BSD 3-Clause "New" or "Revised" License

下载



GitHub Actions: CI


GoReportCard

deep-copy

deep-copy is a tool for generating DeepCopy() functions for a given type.

Given a package directory, and a type name that appears in that package, a
DeepCopy method will be generated, to create a deep copy of the type value.
Members of the type will also be copied deeply, recursively. If a member T of
the type has a method DeepCopy() [*]T, that method will be reused. Multiple
types can be specified for the given package, by adding more --type
parameters.

To specify a pointer receiver for the method, an optional --pointer-receiver
boolean flag can be specified. The flag will also govern whether the return
type is a pointer as well.

To specify build tags in the generated code, an optional --tags comma separated
list flag can be specified. The flag will add all items as build tags to the
generated code.

It might also be desirable to skip deeply copying certain fields, slice
members, or map members. To achieve that, selectors can be specified in the
optional comma-separated --skip flag. Multiple --skip flags can be
specified, to match the number of --type flags. For example, given the
following type:

  1. type Foo struct {
  2. J *int
  3. B Bar
  4. }
  5. type Bar struct {
  6. I *int
  7. }

Leaving the ‘B’ field as a shallow copy can be achieved by specifying --skip B. To skip deeply copying the inner ‘I’ field, one can specify --skip B.I.
Slice and Map members can also be skipped, by adding [i] and [k]
respectively.

To specify a max depth of deep copying, use --maxdepth option. It stops
deep copying at a given depth, with a warning message spotting a place
the deep copying has been stopped. It might especially be useful when
one or more structs have circular references.

To change a method name of deep copying, use --method option.

Usage

Pass either path to the folder containing the types or the module name:

  1. deep-copy <flags> /path/to/package/containing/type
  2. deep-copy <flags> github.com/globusdigital/deep-copy
  3. deep-copy <flags> github.com/globusdigital/deep-copy/some/sub/packages

Here is the full set of supported flags:

  1. deep-copy \
  2. [-o /output/path.go] \
  3. [--method DeepCopy] \
  4. [--pointer-receiver] \
  5. [--skip Selector1,Selector.Two --skip Selector2[i], Selector.Three[k]]
  6. [--type Type1 --type Type2\ \
  7. [--tags mytag,anotherTag ] \ \
  8. /path/to/package/containing/type

Example

Given the following types:

  1. package pkg
  2. type Foo struct {
  3. Map map[string]*Bar
  4. ch chan float32
  5. baz Baz
  6. }
  7. type Bar struct {
  8. IntV int
  9. Slice []string
  10. }
  11. type Baz struct {
  12. String string
  13. StringPointer *string
  14. }

Running deep-copy --type Foo ./path/to/pkg will generate:

  1. // Code generated by deep-copy --type Foo ./path/to/pkg; DO NOT EDIT.
  2. package pkg
  3. // DeepCopy generates a deep copy of Foo
  4. func (o Foo) DeepCopy() Foo {
  5. var cp Foo
  6. cp = o
  7. if o.Map != nil {
  8. cp.Map = make(map[string]*Bar, len(o.Map))
  9. for k, v := range o.Map {
  10. var cpv *Bar
  11. if v != nil {
  12. cpv = new(Bar)
  13. *cpv = *v
  14. if v.Slice != nil {
  15. cpv.Slice = make([]string, len(v.Slice))
  16. copy(cpv.Slice, v.Slice)
  17. }
  18. }
  19. cp.Map[k] = cpv
  20. }
  21. }
  22. if o.ch != nil {
  23. cp.ch = make(chan float32, cap(o.ch))
  24. }
  25. if o.baz.StringPointer != nil {
  26. cp.baz.StringPointer = new(string)
  27. *cp.baz.StringPointer = *o.baz.StringPointer
  28. }
  29. return cp
  30. }