Вызов одной и той же функции для двух разных структур - PullRequest
0 голосов
/ 26 марта 2019

У меня есть две функции, которые принимают разные указатели, указывающие на разные структуры, но структуры имеют одну и ту же основную функцию.

func Save(db *sql.DB) error {
  db.Prepare(query)
}

func TxSave(tx *sql.Tx) error {
  tx.Prepare(query)
}

Я не хочу вносить изменения в обе функции, когда мне нужно расширить эту функцию в будущем. Как мне придерживаться СУХОСТИ в Голанге с этим сценарием?

Ответы [ 2 ]

2 голосов
/ 26 марта 2019

Создайте интерфейс, такой как:

type SQLRunner interface{
    Prepare(query string) (*sql.Stmt, error)
    PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
    Query(query string, args ...interface{}) (*Rows, error)
    QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
    // add as many method shared by both sql.Tx qnd sql.DB
    // ...
} 

И затем создайте один метод, использующий этот интерфейс:

func Save(s SQLRunner) error {
    s.Prepare()
}

В реализации интерфейса go неявно, так что вам просто нужно пройти* sql.Tx или * sql.DB для функции сохранения:

Save(tx)
Save(db)

Вот хороший пост в блоге об интерфейсах в go: http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go

0 голосов
/ 26 марта 2019

Ух ты, я думаю, я влюблен в Го. Я могу просто сделать это, создав собственный интерфейс.

type Saver interface {
  Prepare(query string) (*sql.Stmt, error)
}

func Save(db *sql.DB) error {
  return GenericSave(db)
}

func TxSave(tx *sql.Tx) error {
  return GenericSave(tx)
}

func GenericSave(saver Saver) error {
  stmt := saver.Prepare(query)
  // Do rest with saver
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...