You can create a de-referenced copy of a struct:
package main
import "fmt"
type MyStruct struct {
ID int
}
func main() {
myStruct := &MyStruct{ID: 1}
var myStruct2 = new(MyStruct)
myStruct2 = myStruct
*myStruct2 = *myStruct // de-referenced shallow copy
myStruct2.ID = 2 // doesn't modify myStruct
fmt.Printf("%p %v\\n", myStruct, myStruct)
fmt.Printf("%p %v\\n", myStruct2, myStruct2)
var myStruct3 = new(MyStruct)
myStruct3 = myStruct
myStruct3.ID = 3 // modifies myStruct
fmt.Printf("%p %v\\n", myStruct, myStruct)
fmt.Printf("%p %v\\n", myStruct3, myStruct3)
myStruct4Value := MyStruct{ID: 4}
myStruct5 := &myStruct4Value
myStruct5.ID = 5 // modifies myStruct4Value
fmt.Printf("%p %v\\n", &myStruct4Value, myStruct4Value)
fmt.Printf("%p %v\\n", myStruct5, myStruct5)
}
Source: https://stackoverflow.com/a/21011115/9022642
Cannot be done in base Go.
Requires custom function or external libraries. e.g. https://github.com/barkimedes/go-deepcopy, https://github.com/qdm12/reprint
Advanced struct ↔️ JSON handling in Go
Marshal
/Unmarshal
vs Encode
/Decode
https://dev.to/jpoly1219/to-unmarshal-or-to-decode-json-processing-in-go-explained-5870
In general, Encode
/Decode
takes less memory, but other than that use whichever is easiest for the data type you’re working with
Modified version from source
package singleton
import (
"fmt"
"os"
"sync"
)
type single struct{
myAPIKey: string
}
var (
instance *single
once sync.Once
)
// Returns the singleton instance.
func GetInstance() (*single, error) {
var err error
once.Do(func() {
apiKey, ok := os.LookupEnv("MY_API_KEY")
if !ok || len(apiKey) == 0 {
err = fmt.Errorf("missing my API key")
return
}
instance = single(apiKey)
})
if instance == nil || err != nil {
return nil, fmt.Errorf("cannot instantiate singleton: %w", err)
}
return instance, nil
}
func DestroyInstance() {
instance = nil
once = sync.Once{}
}
package main
import (
"fmt"
. "math" // All of math's exported members now directly available
)
func main() {
fmt.Println(Pi) // 3.141592653589793
fmt.Println(Sin(Pi / 2)) // 1
}
// Go 1.20+
var (
err1 = errors.New("Error 1st")
err2 = errors.New("Error 2nd")
)
func main() {
err := err1
err = errors.Join(err, err2)
fmt.Println(errors.Is(err, err1)) // true
fmt.Println(errors.Is(err, err2)) // true
}