Still trying to wrap my head around how to use and covert */&whatever?

Given the following interface

type Entity interface {
	Key() *datastore.Key
	Uuid() uuid.UUID
	CreatedOn() time.Time
}

This is what I want:

func NewAccount(uuid uuid.UUID, owner *person.Person, createdOn time.Time) *Account {
	key := datastore.NameKey(KIND, uuid.String(), owner.Key()) //<- this complains with "Cannot use 'owner.Key()' (type datastore.Key) as type *Key"
	return &Account{key: key, Owner: *owner, createdOn: createdOn.UTC().Format(time.RFC3339Nano)}
}

But it complains about ownerKey when I try and pass it to datastore.NameKey with

“Cannot use ‘owner.Key()’ (type datastore.Key) as type *Key”

I can get it to stop complaining with:

func NewAccount(uuid uuid.UUID, owner *person.Person, createdOn time.Time) *Account {
	ownerKey := owner.Key()
	key := datastore.NameKey(KIND, uuid.String(), &ownerKey)
	return &Account{key: key, Owner: *owner, createdOn: createdOn.UTC().Format(time.RFC3339Nano)}
}

I have tried everything I can trying to get it to stop complaining with what I have read but I can not get the mix of ()/&/* to satisfy it inline.

What is the magical incantation to get this to reference/dereference inline instead of having to use an intermediate variable?

PS: this is using the google cloud datastore and it requires the *datastore.Key

I don’t think you can - just use an intermediate variable.

I guess there might be some bit of extreme cleverness which means you don’t have to, but Go discourages that in general!

1 Like

Why does (*person.Person).Key return a datastore.Key instead of a *datastore.Key if the common usage is as a pointer? Can you refactor person.Person to not do that? If not, you could box this into a function:


func KeyPtrOf(kr interface{ Key() datastore.Key }) *datastore.Key {
    temp := kr.Key()
    return &temp
}

The relevant part of the language specification about the address operator is here.

There seems to be special cases to allow taking the addresses of literals to combine allocation and initialization but other than that special case, it seems that you can only take the addresses of variables or anything that you can derive from variables (e.g. indexes into slice variables, fields of struct variables, recursively). That’s not exactly what the spec. says, but it seems to be the gist!

2 Likes

This is what I have and it still does not want to let me inline that reference.

func NewKey(p *Person) *datastore.Key {
	if p.Uuid == "" {
		p.Uuid = uuid.NewV5(uuid.Nil, p.Email).String()
	}
	return datastore.NameKey(KIND, p.Uuid, parentKey)
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.