Original post

There is some case where some of the struct in GoLang which is not meant to be copied. For example, sometimes a global configuration which should have only one version passed around the whole application and should not be copied and modified.

In GoLang, there is no intuitive solution on preventing copying of struct. But there is still some way which can be leveraged to help prevent this while developing the code. The trick is to define some struct implementing sync.Locker interface and has this struct embedded in any struct not meant to be copied.

// noCopy may be embedded into structs which must not be copied
// after the first use.
//
// See https://golang.org/issues/8005#issuecomment-190753527
// for details.
type noCopy struct{}

// Lock is a no-op used by -copylocks checker from ` vet`.
func (*noCopy) Lock() {}
func (*noCopy) UnLock() {}

Below is a sample snippet explaining above.

package main

import (
        "fmt"
)

type noCopy struct{}

func (*noCopy) Lock()   {}
func (*noCopy) Unlock() {}

type Demo struct {
        noCopy noCopy
}

func Copy(d Demo) {
}

func main() {
        d := Demo{}
        fmt.Printf("%+v", d)

        Copy(d)

        fmt.Printf("%+v", d)
}

Now if you run go vet on the main.go file, you will see some errors telling you that your are having some place copying the struct(Copy()).

> go vet main.go
# command-line-arguments
.main.go:16: Copy passes lock by value: main.Demo contains main.noCopy
.main.go:21: call of fmt.Printf copies lock value: main.Demo contains main.noCopy
.main.go:23: call of Copy copies lock value: main.Demo contains main.noCopy
.main.go:25: call of fmt.Printf copies lock value: main.Demo contains main.noCopy

One thing to note here is above approach will not tell compiler to fail the compilation. If you proceed to compile and run it, it would still work. This just provides another hint to go vet which normally we would run before we build the project to check there might be potential issue in our source code.

> go run main.go
{noCopy:{}}{noCopy:{}}

Reference: