How to access unexported embedded structs within composite literals in Golang
Short Answer, you can’t. BUT you can still declare it.
If you have two struct types which is embedded within one another but declared as an unexported type, you will not be able to declare it in a composite type. You can only declare it outside of an composite literal
Came across this while attempting to make use of Kubernetes’ API to declare an Deployment
object.
type Deployment struct {
metav1.TypeMeta
Spec DeploymentSpec
}
// in the metav1 pacakge
type TypeMeta {
Kind string
}
With the above structure, when we try to declare Kind
from TypeMeta
within Deployment
, we will get an error indicating an unknown field
of TypeMeta
.
test := Deployment{metav1.TypeMeta: {Kind: "Test"}, Spec: Spec{}}
This is because metav1.TypeMeta
is declared as a unexported type within Deployment
with its lowercase reference.
In order to declare a Kind, you have to declare it from outside.
test := Deployment{Spec: Spec{}}
test.Kind = "Hello"
This is because exported fields (Kind
) keep their exported status when that type is embedded.
2021 Update
It seems when I wrote this in 2017 I might have been mistaken about what constitutes an unexported field. metav1.TypeMeta
here does not seem to be unexported. I’m not sure what is the original error I might have seen back then. In hindsight, I should have been more verbose and documented the actual error here so that when revisiting this issue there would be better context.