nikoss
nikoss

Reputation: 3668

Embedding structs in golang gives error "unknown field"

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

Upvotes: 13

Views: 15271

Answers (2)

Andy Schweig
Andy Schweig

Reputation: 6749

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

Upvotes: 18

hassansin
hassansin

Reputation: 17498

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

Upvotes: 10

Related Questions