In this case I mean within the boundaries of a single package. I realize there is no way to enforce another package maintainer to call the method wrapper rather than the field directly, but I was wondering if people have come up with naming conventions such as a leading underscore to make it apparent that certain fields shouldn't be accessed directly under most circumstances.
On Friday, November 17, 2017 at 10:27:05 PM UTC-8, Nicholas Hanley wrote: > > In Go, lowercase identifiers are not visible outside the package in which > they are defined (ref: Exported identifiers > <https://golang.org/ref/spec#Exported_identifiers>). Your example > declares foo in the main package but I assume your real code would be in > its own package. What you can do is export Foo and GetBar, but leave the > bar field unexported. > > Your code would look something like this: > main.go > package main > > import ( > "fmt" > > "example.com/baz" > ) > > func main() { > f := baz.Foo{} > fmt.Printf("f.bar lazy-loaded: %v\n", f.GetBar()) > } > > example.com/baz/foo.go > package baz > > type Foo struct { > bar string > } > > // Method wrapper that does lazy-loading > func (f *Foo) GetBar() string { > if f.bar == "" { > // lazy-load this from a database or some other expensive call > f.bar = "bar" > } > return f.bar > } > > > On Friday, November 17, 2017 at 4:00:27 PM UTC-5, Traun Leyden wrote: >> >> >> >> I'm trying to figure out a way to best signal to other developers >> maintaining a single package that a field is unsafe to access directly. In >> this case, it's being lazily loaded, and the only way to ensure it will be >> properly loaded is to access the method wrapper rather than directly >> accessing the field. >> >> For example, see this code <https://play.golang.org/p/Y-Qi3D3QwO>: >> >> type foo struct { >> bar string >> } >> >> // Method wrapper that does lazy-loading >> func (f *foo) getBar() string { >> if f.bar == "" { >> // lazy-load this from a database or some other expensive call >> f.bar = "bar" >> } >> return f.bar >> } >> >> func main() { >> f := foo{} >> fmt.Printf("f.bar directly: %v\n", f.bar) >> fmt.Printf("f.bar lazy-loaded: %v\n", f.getBar()) >> } >> >> >> If you access the field directly, you get an empty value. If you call >> the method wrapper, you get the intended value. >> >> I believe the official answer is just "do the right thing" since you are >> within the package boundaries and have full control. And I'm pretty sure >> the language doesn't provide anything here. >> >> But what I'm wondering -- are there any common conventions or workarounds >> to avoid this pitfall? So far the only idea I've been able to come up with >> is to use underscores and/or comments to clearly mark the field as being >> unsafe to access directly: >> >> type foo struct { >> *_bar* string *// You probably want to use getBar() since this is >> lazily loaded an unsafe to access directly.* >> } >> >> >> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.