Тип данных, который принимает несколько типов интерфейса - PullRequest
1 голос
/ 27 апреля 2020

Я постараюсь объяснить свою ситуацию здесь.

Итак, я создаю DAL для своего приложения. Он обращается как к Redis, так и к mysql.

Интерфейс Redis имеет вид:

Файл NoSqlDBClient. go:

type NosqlDb interface {
     HGet() string
}

type NosqlClient struct {
    key string
}

func GetNosqlClient() *NosqlClient{
    return &NosqlClient{}
}

func (ns *NosqlClient) HGet()string {
//actual implemenation would be different
    return ns.key
}

Файл SqldbClient. go:

type SqlDB interface {
    ExecQuery()
}

type SqlClient struct {
    query string
}

func GetsqlClient() *SqlClient{
    return  &SqlClient{}
}

func (s *SqlClient) ExecQuery()string {
    //actual implemenation would be different
    return s.query
}

Теперь мне нужно реализовать фабрику DBClient, которая поддерживает карту типа dbtype и клиента. Это выглядит следующим образом:

Файл DBClientFactory. go

type DBClientfactory struct {
    clientmap[string] //what data type to use???
}

func GetNoSqlDBClient() NosqlDb{
    client:=NoSqlDBClient.GetNosqlClient()
    clientmap['nosql'] = client
    return client
}

func GetSqlDBClient() SqlDB{
    client:=SqlDBClient.GetsqlClient()
    clientmap['sql'] = client
    return client
}

Проблема в том, как я могу держать разные типы клиентов на одной карте? Я думал об определении другого интерфейса DBFactory, в который встроены два других интерфейса. Но это, очевидно, не работает, потому что все методы не реализуются отдельным интерфейсом.

Как мне go узнать об этой проблеме?

1 Ответ

1 голос
/ 27 апреля 2020

Вы можете использовать interface{} для типа значения карты, но тогда вы потеряете безопасность типов и вам придется использовать утверждения типа или переключатели типов.

Вместо этого вы должны использовать 2 различных типа карты, по одному для каждого интерфейс, который вы хотите сохранить:

type DBClientfactory struct {
    nosqldbs map[string]NosqlDb
    sqldbs   map[string]SqlDB
}

И каждая функция или метод будет использовать соответствующую карту, GetNoSqlDBClient() будет использовать DBClientfactory.nosqldbs, а GetSqlDBClient() будет использовать DBClientfactory.sqldbs.

Если у вас есть только один экземпляр каждого клиента, тогда вообще не используйте карту, просто используйте простые поля:

type DBClientfactory struct {
    nosqldb NosqlDb
    sqldb   SqlDB
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...