Mar 25, 2021

[Go]noCopy trick

 Reference:
https://github.com/golang/go/blob/374b1904750931ed09d342e3c4c6e01fdb2802aa/src/sync/cond.go#L94
https://github.com/golang/go/issues/8005#issuecomment-190753527

quote RSC:

There have been a number of OK-but-not-obviously-right proposals for saying "you can't copy this". My view of the situation is:

Go doesn't support this today, and in fact it used to but we took that out.

The original motivation here was sync.Mutex, which is handled by the current cmd/vet copylock check (which looks for a Lock method), and sync.Cond, which isn't handled but could easily be added to vet in some way.

The most common way to create types that cannot be copied is to embed a sync.Mutex, and those types are already handled by the cmd/vet check.

Instead of building more generality into vet as a kind of back-door language change, let's leave things alone for now - without any attempt to expand the generality of the copylock check - and wait to see if a better idea or more compelling evidence comes along. We should probably also make sure vet understands that sync.Cond cannot be copied, if it does not already. I opened a separate issue for that: #14582.

Note that code that absolutely must opt in to the vet check can already do so. A package can define:

type noCopy struct{}
func (*noCopy) Lock() {}

and then put a noCopy noCopy into any struct that must be flagged by vet.

--end quote--

Thus;

// 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 `go vet`.
func (*noCopy) Lock()   {}
func (*noCopy) Unlock() {}
Which whenever a struct embedded noCopy can only pass in interface as pointer type.


package main


type noCopy struct{}

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


type I1 interface{
    Lock()
    UnLock()
}

type Fun struct{
    noCopy
}

func main() {

    f1 := Fun{}
    f2 := f1
    _ = f2

    var i1 I1 = &f1

    _ = i1
}

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.