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.