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: don't export methods of non-exported anonymous fields for the embedding type #21892
Comments
If you do this then If you have
what happens when another package calls that? |
sync.Locker has methods of Lock and Unlock. So it is ok for the return value to call the two methods. func Exported() sync.Locker {
return &unexported{}
}
type unexported struct{sync.RWMutex} |
Doesn't that defeat the purpose of hiding those methods from external packages? |
no, exposing non-exported methods through interface is a recommended pattern. |
@go101 What is the purpose of this proposal? It doesn't seem to let Go programs do anything they can't do today, so what errors does it help them avoid? It's already easy to not export the methods of an embedded field: don't embed the field. The local package can already call the methos on a named unexported field. |
Yes
Yes, it may be not hard, |
The whole point of embedding a type rather than making it a field is to have the methods and fields of the type get lifted to the containing struct. You seem seem to be arguing that you don't want that to happen..... but then why embed the type? |
methods are still lifted in the current package internal, they are just not exported to external packages. |
Every change to Go has benefits and drawbacks. Every language change starts with an automatic drawback: people have to learn something new. When proposing a language change, you need to clearly explain the benefits of the change. So far the only benefits I see are that this proposal is "more logical" and that the current approach is "verbose and not that beautiful." To me those benefits do not seem nearly large enough to overcome the drawback of changing the language. |
At least, they are some reasonable reasons. :) And, for Go 2, for every case like the following one: type ExportedT struct {
nonExportedButWithSomeMethods
}
type TnonExportedButWithSomeMethods = struct{nonExportedButWithSomeMethods}
type ExportedT struct {
TnonExportedButWithSomeMethods
} |
Which make the code more "verbose and not that beautiful." IMHO - which is your argument to add the new behavior. |
|
As I wrote in #18130, "restrictions add complexity" (see the Restrictions section). This proposal directly conflicts with the goal of type aliases, which is that the two types are essentially indistinguishable.
If the method is named Lock, the method is exported. That's just how it works. Note that if you do
and embed that, then you still get an exported method If you want Lock/Unlock exported, embed. If you don't, name the field (don't embed), like:
and then use foo.m.Lock instead of foo.Lock. It's slightly longer but it keeps the rules regular and predictable. |
This is a Go 2 proposal.
Now, the exported methods of sync.RWMutex will be exported for types embedded its non-exported alias.
To make the methods of
rwMutex
not exported,rwMutex
mustn't be embedded anonymously now.As SyncedInitMap.rwMutex is not exported, it is more logical that its methods are also not exported.
The text was updated successfully, but these errors were encountered: