While calling json.Decoder.Decode by passing a struct, for instance
type _Sample struct {
first string // this will not be filled because it starts with lower case letter
Second string // it is OK.
}
...
var sample _Sample
err := decoder.Decode(&sample)
According to the Language Specification that writes:
Exported identifiers ¶
An identifier may be exported to permit access to it from another package. An identifier is exported if both:
- the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and
- the identifier is declared in the package block or it is a field name or method name.
All other identifiers are not exported.
The question is the struct _Sample
is not exported, why it is visible by the package json
?
Access permission is checked when
reflect
package to modify a variable.Once the variable is created/defined, and when you pass this variable as a function/method argument, the copy (If it is a value, the value is being copied. If it is a pointer, the address is being copied) will be passed to the function/method, and always accessible from the function body through the argument name and type. In encoding/json
package, the Decoder.Decode
method is defined as,
func (dec *Decoder) Decode(v interface{}) error
thus, anything you passed to the Decoder.Decode
method, is always accessible from inside the method body through argument v
. Note that the type of v
is interface{}
not _Sample
struct. The visibility is checked when you defined the variable as
var sample _Sample
which was OK since it is done from within the same package. Even an anonymous struct (i.e. no type name identifier is defined for the struct)
aSample := struct {
first string // this will not be filled because it starts with lower case letter
Second string // it is OK.
}{}
//...
err := decoder.Decode(&aSample)
will works. Next, when the decoder
fills the struct (through reflection), the visibility of struct members will be checked, and _Sample.first
is not visible from inside the json
package.