Just use a comment. That's usually fine. // this is lazy loaded, use getBar() instead of directly accessing.
"Don't do that" is a surprisingly feasible solution to a lot of programming problems. Not everything has to be enforced by tooling. On Sunday, November 19, 2017 at 9:08:47 PM UTC-5, Traun Leyden wrote: > > > 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.