Embedding structs in golang gives error "unknown field"
Solution 1
You are trying to initialize promoted fields which is not possible by composite literals. From Go spec:
A field or method f of an anonymous field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f.
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
But you can access them using dot notation:
ra:= returnAccount{}
ra.Tp = acnt.Tp
Solution 2
You can't initialize the fields in the embedded type directly, but you can do it like this:
accounts[v.AccountId] = returnAccount{
Account: Account{
Tp: v.Tp,
AccountId: v.AccountId,
Username: v.Username,
},
}
Or, if v
is of type Account
, you can just use
accounts[v.AccountId] = returnAccount{
Account: v,
}
nikoss
Updated on June 24, 2022Comments
-
nikoss about 2 years
i have a
struct
inuser
package calledaccount
type Account struct { Tp string `json:"type"bson:"type"` AccountId string `json:"account_id"bson:"account_id"` Credentials map[string]interface{} `json:"credentials,omitempty"bson:"credentials,omitempty"` ProfilePicture string `json:"profile_picture,omitempty"` Username string `json:"username"bson:"username"` AccessToken map[string]interface{}`bson:"access_token,omitempty"` }
and in
user/accounts
im trying to embed this account struct into another structtype returnAccount struct { user.Account AccessToken string `json:"access_token,omitempty"` }
user package is properly imported before trying to embed i was using it successfully
finaly in a loop i am getting user accounts and making a map of
returnAccount
and returning from my function here is my functionfunc getAccounts(usr *user.AuthenticatedUser, id ...string) (accounts map[string]returnAccount) { accounts = make(map[string]returnAccount) if len(id) > 0 { for _, v := range id { for _, acnt := range usr.Accounts { if acnt.AccountId == v { accounts[acnt.AccountId] = returnAccount{ Tp: acnt.Tp, AccountId:acnt.AccountId, } } } } return } for _, v := range usr.Accounts { accounts[v.AccountId] = returnAccount{ Tp: v.Tp, AccountId:v.AccountId, Username: v.Username, } } return }
However this code wont compile here is the error message
# sgin/api/user/accounts api/user/accounts/getaccounts.go:16: unknown returnAccount field 'Tp' in struct literal api/user/accounts/getaccounts.go:17: unknown returnAccount field 'AccountId' in struct literal api/user/accounts/getaccounts.go:26: unknown returnAccount field 'Tp' in struct literal api/user/accounts/getaccounts.go:27: unknown returnAccount field 'AccountId' in struct literal api/user/accounts/getaccounts.go:28: unknown returnAccount field 'Username' in struct literal
everything seems pretty straightforward and simple i cannot figure out why i get this error all members i need to reach of the Account struct are exported
The reason why i need this field is i want to send access token to clients through api but not the secret and also i want to reduce the indention level
-
nikoss over 7 yearsthis solves the issue though i couldnt quite understand the topic can you please ad some more detail i checked the spec but the meanin is not very clear @hassansin
-
Andy Schweig over 7 yearsAlso see my answer for a way to do it without having to use separate assignments.
-
nikoss over 7 yearsthis is not the case this vill make one exta level of indention i need to embed account directly under returnAccount
-
Andy Schweig over 7 yearsThe indentation is irrelevant. This just shows how you can set those fields in a literal as opposed to doing it with separate assignments. You don't have to do it this way if you don't want to, but it's identical to what you were trying to do. Please remove your down vote as this answer is correct.
-
nikoss over 7 yearsunless you edit the question the site does not allow me to remove the vote and the point is that the account struct will keep growing as the program needs more details i dont want to type all changes to 2 or more places by hand its not the way i prefer to write programs
-
nikoss over 7 yearscan you make a minor change to your post so i can upvote actually i solved the issue your way
-
erik258 over 4 yearsThere you go @nikoss, it finally happened