Struct Exported or Unexported - Can I get a warning?

So I lost half a day to not understanding Exported vs Unexported in relation to a struct.
Happy to say I should have read the docs.

What I got was code that compiled with no errors, but use of Unexported members of the struct gave me no data, or in my case an empty string.

is it possible to get an error or warning when trying to access an Unexported member of the struct?

I am not talking about changing the rules of struct’s, but i am looking for some kind of warning for when I do dumb things.

What exactly do you mean by this? Can you show us a small sample of such a struct?

And how is code using the members of this struct? What exactly to you mean by “use of Unexported members”? How are they used?

1 Like

@lutzhorn I think he means something like this:

type ABC struct{
   field1 int
   field2 string
}

instead of

type ABC struct{
   Field1 int
   Field2 string
}

@Derek_Robson Try using go lint tool. That catches such issues in my knowledge.

Yes, probably.

But the interesting point is how code is using this struct. There are good reasons to export or to not export members. As long as we don’t know how the struct is to be used, we can neither advise on exporting nor can we help solving the problem.

1 Like

Understood.

I just assumed it was something JSON related perhaps, because he did not get any errors.

@Derek_Robson,
If you are infact using unexported members of a struct in a different package, that should throw an error because it cannot identify such a struct member.

Here is some example code that is broken.

My use case is to import a config via yaml file and have it available across all functions.
I know I can make it work if I use a Capital letter at start of struct member name.

My real point is that the example below is “broken” yet give no errors or warnings.
Should go give me a warning that I am doing stupid things?

I am sure there are many ways to make the code work, but should it give me an error?
This is less about how i should write my code, but tips are welcome, its more that this complies fine and won’t work.

package main

import (
        "fmt"
        "log"
        "gopkg.in/yaml.v2"
)

var data = `
a: Easy!
`

type Test struct {
        aA string
}

var test Test

func main() {
        err := yaml.Unmarshal([]byte(data), &test)
        if err != nil {
                log.Fatalf("error: %v", err)
        }
        fmt.Printf("test.aA =: %v\n", test.aA)
}
1 Like

You are refering to the behaviour described here:

The json package only accesses the exported fields of struct types (those that begin with an uppercase letter). Therefore only the the exported fields of a struct will be present in the JSON output.

And:

Unmarshal will decode only the fields that it can find in the destination type. […] It also means that any unexported fields in the destination struct will be unaffected by Unmarshal .

Since reflection is used from outside your module, only exported members are visible to the library code that looks for members to populate. It has no way to even know that there are unexported members that might match JSON/YAML object properties.

From the POV of the library code populating the members, this is a good thing. Unexported members are for internal use of the strcut and not to be messed with by code external to the module.

So, no, there is no way a warning can be issued.

Yep, that explains it.
Today I have learned things.

Thanks for fast response.
Solved.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.