避免在Golang中使用接口复制代码

I am using the Google Cloud Datastore (or the google app engine datastore), to store different objects. Most of these objects are similar, hence I end up with lots of code duplication.

As an example, here are two create methods, of two different objects, account and index.

func (account *Account) Create(ctx context.Context) (*Account, error) {
  if ret, err := datastore.Put(ctx, account.newKey(ctx), account); err != nil {
    log.Errorf(ctx, "Error while creating Account : %v
", err)
    return nil, err
  } else {
    account.Id = strconv.FormatInt(ret.IntID(), 10)
  }

  return account, nil
}

func (index *Index) Create(ctx context.Context) (*Index, error) { 
  if ret, err := datastore.Put(ctx, index.newKey(ctx), index); err != nil {
    log.Errorf(ctx, "Error while creating Index : %v
", err)
    return nil, err
  } else {
    index.Id = strconv.FormatInt(ret.IntID(), 10)
  }

  return index, nil
}

As you can see, the two snippets are identical, excepts for the holder type, the return type, and the error message.

What is the idiomatic way to avoid this kind of code duplication ?

Use interface to define methods NewKey() & SetID()

type Entity interface {
  SetId(id int64)
  NewKey(c context.Context) *datastore.Key
}

func create(c context.Context, entity Entity) error { 
  if ret, err := datastore.Put(c, entity.NewKey(c), entity ); err != nil {
    log.Errorf(c, "Error while creating entity: %v
", err)
    return err
  } else {
    entity.SetId(ret.IntID())
    return nil
  }
}

func (index *Index) Create(c context.Context) (*Index, error) {
  return index, create(c, index)
}

func (account *Account) Create(c context.Context) (*Account, error) {
  return account, create(c, account)
}