cpy

package
v0.0.0-...-a9c933c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 18, 2021 License: BSD-3-Clause Imports: 3 Imported by: 6

Documentation

Overview

Package cpy copies Go objects.

This package provides a generic way of deep copying Go objects. It is designed with performance in mind and is suitable for production use. By design, it does not handle unexported fields. If such fields need copying, it is the responsibility of the user to provide a custom copy function to specify how a specific type should be copied.

WARNING: This package's API is currently unstable and may change without warning. If this matters to you, you should wait until version 1.0 is released before using it.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Copier

type Copier struct {
	// contains filtered or unexported fields
}

A Copier copies Go objects.

func New

func New(opts ...Option) *Copier

New initializes a new Copier according to the provided options.

Example usage:

// As a global variable.
var copier = cpy.New(
	cpy.Func(proto.Clone),
	cpy.Shallow(time.Time{}),
)

// Elsewhere in application code.
dst := copier.Copy(src)

It is recommended that the Copier returned by New be stored in a global variable so that it can be reused.

func (*Copier) Copy

func (c *Copier) Copy(v interface{}) interface{}

Copy copies v according to the Copier presets.

Values are copied according to the following rules:

• Zero values (according to reflect.Value.IsZero) are returned as is.

• If the current type matches a Func provided to New, then the specialized copy function is used to copy the value. Precedence is given to Funcs that operate on concrete types, then Funcs that operate on interface types, then the behavior listed below. For Funcs operating on the same type, those passed later to New take precedence over any preceding Func arguments.

• Pointers are copied by allocating a new value of the same type and recursively calling Copy on the pointed-at value.

• Interfaces are copied by recursively calling Copy on the underlying source value and casting the resulting concrete value to the same interface type.

• Arrays and slices are copied by making a new array or slice of the same type (with the same length and capacity for slices). Every element in the source is recursively copied by calling Copy and storing the result into the destination array or slice.

• Maps are copied by making a new map of the same type and recursively calling Copy on each map key and map value in the source and storing the result into the newly made destination map.

• Structs are copied by creating a new struct of the same type and recursively calling Copy for each field in the source and storing the result into the destination struct. It panics when trying to copy a struct type with unexported fields unless an IgnoreAllUnexported option was passed to New, in which case unexported fields are ignored. Alternatively, a custom Func may be specified to provide a specialized implemention of deep-copying for the type with unexported fields based on the exported API for that type.

• Lastly, all other types (e.g., int, string, etc.) are shallow copied. Note that unsafe.Pointer and channels are shallow copied since there is no obvious behavior to use to deep copy such types.

The output type is guaranteed to be the same as the input type. Copy will panic if that invariant is violated by a provided Func. Copy presently does not handle cycles in the value and will overflow.

type Option

type Option option

Option is an option that configures a Copier. An option must be obtained using a constructor (e.g., Func or Shallow).

func Func

func Func(fn interface{}) Option

Func provides specialized copy behavior for specific types.

The copy function f must be a function "func(T) T", where T must be a pointer, interface, array, slice, map, or struct; otherwise it will panic. If T is an interface type, it must have at least one method, otherwise Func will panic. Futhermore, the function must return a concrete type identical to the input type, otherwise Copier.Copy will panic.

The Func will be used if the current type of the value being copied exactly matches the input type (for concrete types) or if it implements the input type (for interface types). Both the type itself (e.g., T) and a pointer to the type (e.g., *T) are checked when evaluating whether a given Func can be used.

Example usage:

cpy.Func(proto.Clone)

This option specifies that proto.Clone is used to copy all types that are assignable to the proto.Message interface.

func IgnoreAllUnexported

func IgnoreAllUnexported() Option

IgnoreAllUnexported specifies that Copy should ignore all unexported fields as opposed to panicking when encountering an unexported field.

func Shallow

func Shallow(typs ...interface{}) Option

Shallow specifies that the provided type should be shallow copied. The provided type must be a pointer, interface, array, slice, map, or struct; otherwise it will panic.

Shallow is equivalent to:

cpy.Func(func(v V) V { return v })

Example usage:

cpy.Shallow(time.Time{})

Since the fields of time.Time are unexported, the default behavior of Copier.Copy will functionally avoid copying the time value. This option specifies that time.Time is a value that is safe to shallow copy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL