Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Go 2: non-copyable structs by default #30450

Closed
taralx opened this issue Feb 28, 2019 · 10 comments
Closed

proposal: Go 2: non-copyable structs by default #30450

taralx opened this issue Feb 28, 2019 · 10 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@taralx
Copy link

taralx commented Feb 28, 2019

Most structs are actually not safe to copy. Most code handles structs by pointer because it is the best way to avoid accidentally copying it. (And there's hard-coding to prevent sync.Mutex being copied because of how often that mistake got made!)

Go 2 should accept this reality and make structs non-copyable by default. The copy() method could be extended to allow struct copying, and people who really want copyable structs can provide a method to call copy() for you.

Note that this doesn't stop moves of structs, e.g. returning them. Accepting them by value is a more complex question, since it introduces the possibility of an "empty" variable in many cases.

@gopherbot gopherbot added this to the Proposal milestone Feb 28, 2019
@ianlancetaylor ianlancetaylor added LanguageChange v2 A language change or incompatible library change labels Feb 28, 2019
@ianlancetaylor
Copy link
Contributor

This would make it impossible to use structs as map keys.

@taralx
Copy link
Author

taralx commented Feb 28, 2019

Good point. Most structs shouldn't be used as map keys, but we want that to work. What about having a way to mark structs as copyable then? Some small keyword, perhaps? Obviously copyable structs can't contain non-copyable structs.

@taralx
Copy link
Author

taralx commented Feb 28, 2019

(I'm assuming we don't want to open the box of comparable but non-copyable types.)

@robpike
Copy link
Contributor

robpike commented Feb 28, 2019

Many structs are safe to copy, though. The sort of thing you're asking for is a property of languages with a different philosophy from Go and doesn't fit well in Go's model.

@taralx
Copy link
Author

taralx commented Feb 28, 2019

Would it work if it used package boundaries? Structs with inaccessible fields are non-copyable?

@bcmills
Copy link
Contributor

bcmills commented Feb 28, 2019

See previously #23764 and #8005.

@taralx
Copy link
Author

taralx commented Feb 28, 2019

Thanks, that's useful background. Should I write up the accessibility-based proposal in more detail?

@ianlancetaylor
Copy link
Contributor

A current way to declare that a struct is not copyable is to add both a Lock and Unlock method, even if the method doesn't do anything. That will cause "go vet" to complain about attempts to copy the struct. If you don't want to expose the methods, you can instead add them to a zero-length unexported struct, and embed that struct in the exported one. See, e.g., https://play.golang.org/p/ovFyFQHzZFH (the playground will run "go vet" when you click on the "Run" button).

We are not going to change the default for how structs work in Go, so closing this specific issue.

@go101
Copy link

go101 commented Mar 27, 2019

It looks embedding a non-exported struct doesn't prevent the methods being exposed: https://play.golang.org/p/oahXcIL11j3

@go101
Copy link

go101 commented Mar 27, 2019

It looks std packages use non-embedding general noCopy fields:
For example:

type WaitGroup struct {
	noCopy noCopy

	state1 [3]uint32
}

@golang golang locked and limited conversation to collaborators Mar 26, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

6 participants