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.

Reply via email to