The xgo contains various useful features for gohers.
- Deep copy
 - Contains
 - Chunk
 - Exponential backoff
 - Struct to map
 - Obtain pointers to types
 
There is an extension package that supports deep copying Protobuf timestamp types.
$ go get github.com/glassonion1/xgo
import "github.com/glassonion1/xgo"field-to-field copying based on matching names.
In layered architecture, there are times when we need to copy values between structs that have different types but share the same field names. The DeepCopy function is designed to be used in such scenarios.
Support for copying data:
- from struct to struct
 - from struct to pointer
 - from pointer to struct
 - from slice to slice
 
package xgo_test
import (
    "fmt"
    "time"
    "github.com/glassonion1/xgo"
)
type FromModel struct {
    ID         string `copier:"Id"`
    Name       string
    CreatedAt  time.Time
    UpdatedAt  *time.Time
}
type ToModel struct {
    Id         string
    Name       string
    CreatedAt  time.Time
    UpdatedAt  *time.Time
}
func Example() {
    now := time.Date(2025, 6, 1, 0, 0, 0, 0, time.UTC)
    from := FromModel{
        ID:        "xxxx",
        Name:      "R2D2",
        CreatedAt: now,
        UpdatedAt: &now,
    }
    to := &ToModel{}
    err := xgo.DeepCopy(from, to)
    if err != nil {
        // handles error
    }
    fmt.Println("ToModel object:", to)
    // Output: ToModel object: &{xxxx R2D2 2025-06-01 00:00:00 +0000 UTC 2025-06-01 00:00:00 +0000 UTC}
}type FromModel struct {
    ID         string
    Name       string
}
type ToModel struct {
    ID         string
    Name       string
}
func Example() {
    from := []FromModel{
        {
            ID: "xxxx1",
            Name: "R2D2",
        },
    {
            ID: "xxxx2",
            Name: "C3PO",
        },
    }
    to := &[]ToModel{}
    err := xgo.DeepCopy(from, to)
    if err != nil {
        // handles error
    }
    fmt.Println("ToModel object:", to)
    
    // Output: ToModel object: &[{xxxx1 R2D2} {xxxx2 C3PO}]
}Contains method for a slice.
// slice of int32
containsInt32 := xgo.Contains([]int32{1, 2, 3, 4, 5}, 3)
fmt.Println("contains int32:", containsInt32)
// slice of int
containsInt := xgo.Contains([]int{1, 2, 3, 4, 5}, 2)
fmt.Println("contains int:", containsInt)
// slice of float64
containsFloat64 := xgo.Contains([]float64{1.1, 2.2, 3.3, 4.4, 5.5}, 4.4)
fmt.Println("contains float64:", containsFloat64)
// slice of string
containsString := xgo.Contains([]string{"r2d2", "c3po", "bb8"}, "c3po")
fmt.Println(containsString) // -> true
// slice of struct
type hero struct {
    ID   string
    Name string
}
list := []hero{
    hero{
        ID:   "1",
        Name: "Luke Skywalker",
    },
    hero{
        ID:   "2",
        Name: "Han Solo",
    },
    hero{
        ID:   "3",
        Name: "Leia Organa",
    },
}
target := hero{
	ID:   "2",
	Name: "Han Solo",
}
containsStruct := xgo.Contains(list, target)
fmt.Println("contains struct:", containsStruct)
// Output:
// contains int32: true
// contains int: true
// contains float64: true
// contains string: true
// contains struct: trueObtain pointers to types
type Vegetables string
const (
	Pea     Vegetables = "Pea"
	Okra    Vegetables = "Okra"
	Pumpkin Vegetables = "Pumpkin"
)
type Model struct {
	ID        *int
	Name      *string
	Material  *Vegetables
	CreatedAt *time.Time
}
func ExampleToPtr() {
	obj := Model{
		ID:        xgo.ToPtr(123),
		Name:      xgo.ToPtr("R2D2"),
		Material:  xgo.ToPtr(Pea),
		CreatedAt: xgo.ToPtr(time.Date(2020, 6, 1, 0, 0, 0, 0, time.UTC)),
	}
	fmt.Println("object:", obj)
}