Embedding structs in golang gives error “unknown field”

家住魔仙堡 提交于 2020-01-14 10:06:54

问题


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:


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



回答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,
}



回答3:


returnAccount should start with upper-case letter to be exported and used within other packages.

In Go, a simple rule determines which identifiers are exported and which are not: exported identifiers starts with upper-case letter.



来源:https://stackoverflow.com/questions/41686692/embedding-structs-in-golang-gives-error-unknown-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!