Обмен информацией между структурами в Голанге - PullRequest
0 голосов
/ 25 ноября 2018

У меня есть общий обработчик, который содержит данные, необходимые для выполнения всего, что он должен делать.

type Handler struct {
    info HandlerInfo
}

Затем структура отправителя, которая в равной степени имеет свою собственную информацию.

type Sender struct {
    info SenderInfo
}

Наконец, есть получатель, который также имеет свою собственную информацию.

type Receiver struct {
    info ReceiverInfo
}

Обработчик генерирует связывающие пары при выполнении программы.Я не хочу приводить примеры типов связи между различными структурами, которые я определил, так как я хочу, чтобы мой пример был максимально широким.

func (h Handler) Do() {
    for /* something happens */ {
        sender := Sender{}
        receiver := Receiver{}
    }
    sender.DoSomething()
    if sender.ShouldSend() {
        receiver.Receive()
    }
}

Здесь все выглядит довольно просто, но ясталкиваются с двумя проблемами:

1) Как обрабатывать данные, передаваемые Отправителем и Получателем без избыточности?

2) Как обрабатывать данные, используемые Обработчиком, но этоОтправитель и Получатель также должны использовать?


1) Как обрабатывать данные, передаваемые Отправителю и Получателю без избыточности?

Кто-то может сказать, что необходимо только заполнить обе структуры поэтапно тем, что им нужно

Но это делает вещи слишком избыточными IMO:

func DoSomethingAndFill() {
    data1 := generateSomeData1()
    recv.Receive1(data1)
    sender.Send1(data1)
    data2 := generateSomeData2()
    recv.Receive2(data2)
    sender.Send2(data2)
}

Я сказал себе, что могу (буквально) разделить базовую структуру, содержащую данные, которые должны быть переданы:

type MetaData struct {
    Data1 Data
    Data2 Data
}

type Sender struct {
    *MetaData
    info SenderInfo
}

type Receiver struct {
    *MetaData
    info ReceiverInfo
}

А при инициализации мне нужно было только поставить тот же указатель?

func init() {
    md := MetaData{}
    recv, send := Receiver{&md}, Sender{&md}
}

Но это заставляет меня делать две вещи:

  • С одной стороны, если я хочу очистить вещи и сделать пакет для Получателя, а другой - для Отправителя, я должен сделать всеполя экспортируемых MetaData, которые, хотя и не сильно плохи, не идеальны.

  • С другой стороны, я вынужден сделать код немного более запутанным, так как при заполненииСтруктура Мне приходится перетаскивать то, что входит в Sender, Receiver и MetaData.


2) Как обрабатывать данные, используемые Handler, но которые Sender и Receiver также должны использовать?

Первое, что мне пришло в голову, это сделать что-то вроде обратной ссылки на родительскую структуру:

type Handler struct {
    Info HandlerInfo
}

type Sender struct {
    handler Handler
    info SenderInfo
}

type Receiver struct {
    handler Handler
    info ReceiverInfo
}

func (h Handler) MakeRecvAndSend() {
    recv, send := Receiver{
        handler: h,
    }, Sender{
        handler: h,
    }
}

И на первый взгляд это кажется довольно хорошим, но опять же, если Senderи Receiver находятся в разных пакетах, и поскольку круговой импорт в Golang не разрешен, это невозможно.

Другое решение, о котором я подумал, - копировать соответствующую информацию по частям:

type Handler struct {
    info1 HandlerInfo
    info2 HandlerInfo
}

type Sender struct {
    handlerInfo HandlerInfo
    info SenderInfo
}

type Receiver struct {
    handlerInfo HanlderInfo
    info ReceiverInfo
}

func (h Handler) MakeRecvAndSend() {
    recv, send := Receiver{
        handlerInfo: h.info1,
    }, Sender{
        handler: h.info2,
    }
}

Но это очень многословно, и, в зависимости от способа генерации отправителей и получателей, я боюсь, что это повлияет на скорость / память во время выполнения.

Если вы уже столкнулись с такими проблемами, я бынравится ваш отзыв и то, как вы решили это.Я также интересуюсь любой теоретической мыслью, которой вы могли бы поделиться!

Thx!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...