英文:
Embedding structs in golang gives error "unknown field"
问题
我在user
包中有一个名为account
的struct
。
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"`
}
在user/accounts
中,我试图将这个account
结构嵌入到另一个结构中。
type returnAccount struct {
user.Account
AccessToken string `json:"access_token,omitempty"`
}
在成功导入user
包之后,我尝试嵌入它,之前一直都能用。
最后,在一个循环中,我获取用户账户并将其映射为returnAccount
,然后从函数中返回。以下是我的函数:
func 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
}
然而,这段代码无法编译,以下是错误信息:
# 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
一切看起来都很简单明了,我无法弄清楚为什么会出现这个错误,我需要访问Account
结构的所有成员都是公开的。
我需要这个字段的原因是,我想通过API将访问令牌发送给客户端,但不包含密钥,同时我还想减少缩进级别。
英文:
i have a struct
in user
package called account
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 struct
type 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 function
func 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
答案1
得分: 16
你不能直接初始化嵌入类型中的字段,但可以像这样操作:
accounts[v.AccountId] = returnAccount{
Account: Account{
Tp: v.Tp,
AccountId: v.AccountId,
Username: v.Username,
},
}
或者,如果v
的类型是Account
,你可以直接使用:
accounts[v.AccountId] = returnAccount{
Account: v,
}
英文:
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,
}
答案2
得分: 10
你正在尝试初始化被提升的字段,但通过复合字面量是不可能的。根据Go规范:
> 在结构体x中,如果匿名字段的字段或方法f被称为被提升的字段,那么x.f是一个合法的选择器,表示该字段或方法f。
>
> 被提升的字段就像结构体的普通字段一样,只是不能在结构体的复合字面量中用作字段名。
但你可以使用点表示法访问它们:
ra := returnAccount{}
ra.Tp = acnt.Tp
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论