Proposal: Export fields and methods of unexported types
This one will require some careful phrasing but the gist of the proposal is:
For unexported types, it's beneficial to export fields or methods to mark them as part of their "public" API is for use by other unexported types.
As a contrived example,
// counter.go
type countingWriter struct {
writer io.Writer
count int
}
func (cw *countingWriter) Write(b []byte) (int, error) {
n, err := cw.writer.Write(b)
cw.inc(n)
return n, err
}
func (cw *countingWriter) inc(n int) {
cw.count += n
}
// another.go
func foo(w io.Writer) error {
cw := &countingWriter{writer: w}
writeABunch(&cw)
fmt.Println("wrote", cw.count, "bytes")
}
It would be useful for the author of countingWriter to indicate which fields they intended to be accessed directly, and which are "private". The example above could be:
type countingWriter struct {
Writer io.Writer
Count int
}
func (*countingWriter) inc(int)
This indicates that int is for private use but the Writer and Count fields may be accessed freely. If the author wanted to protect writes to Count, maybe they'd switch to:
type countingWriter struct {
Writer io.Writer
count int
}
func (*countingWriter) Count() int
Obviously, there's no enforcement and this only works as a general guidance to indicate "publicness" of a field/method of a private type, but as a reader/consumer of a private type in a large package, one might find value in knowing what they should or should not touch.