Преобразование интерфейса: интерфейс {} — это карта[строка]интерфейс {}, а не

У меня есть несколько структур, определенных как

type EventPayload struct {
    IsAdded        bool   `json:"is_added"`
    IsUpdated      bool   `json:"is_updated"`
    IsDeleted      bool   `json:"is_deleted"`
}

type HubEvent struct {
    Time      string      `json:"time"`
    Payload   interface{} `json:"payload"`
}

type EventRecord struct {
    InputEventPayload HubEvent `json:"inputEventPayload"`
    EventID           string         `json:"eventId"`
}

Теперь у меня есть массив EventRecord, по которому мне нужно выполнить итерацию. Мне нужно сделать 2 вещи:

  1. Для каждой eventRecord в массиве мне нужно проверить, существует InputEventPayload или нет.
  2. Если да, мне нужно преобразовать интерфейс InputEventPayload.Payload в структуру EventPayload.

Я создал тестовый файл для проверки своего кода, в который передаю массив EventRecords.

[]EventRecord{
    {
        EventID: "eventID-1",
    },
    {
        EventID: "eventID-2",
        InputEventPayload: HubEvent{
        Payload: EventPayload{
            IsAdded: true,
            IsUpdated: false,
        },
            },
    },
}

Мой код выглядит так

for _, record := range EventRecords {

    // check if the InputEventPayload exists in the record
    if record.InputEventPayload != (HubEvent{}) {

        // typecast
        payload := record.InputEventPayload.Payload.(EventPayload)

        // do something with the payload
    }
}

Я не знаю, правильный ли это способ проверить, существует поле InputEventPayload или нет. Во-вторых, когда код пытается привести тип, он выдает следующую ошибку:

interface conversion: interface {} is map[string]interface {}, not EventPayload

Здесь важно то, что я не могу изменить здесь схему каких-либо структур.

Вы имеете в виду, что вообще не можете редактировать структуру HubEvent? например, чтобы установить Payload *EventPayload ?

LeGEC 05.07.2024 11:45

Да, я вообще не могу редактировать структуру HubEvent.

Anirudh Garg 05.07.2024 11:54

Мне кажется, ваш код в порядке. Я не знаю, почему он сообщает, что это карта, будучи структурой. Вы уверены, что фрагмент повторяется? Вот ваш код дословно, и он не ломается go.dev/play/p/TTi460la7rf

Partho KR 05.07.2024 12:16

Да, я тоже попробовал это там, и оно не сломалось. Странно, почему это происходит с GoLand

Anirudh Garg 05.07.2024 13:38
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
4
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема (также с вашими тестовыми данными) заключается в том, что вы десериализуете JSON в interface{}, создавая объект map[string]interface{} по умолчанию.

Одним из решений может быть повторная сериализация и десериализация:

    for _, record := range EventRecords {
        // check if the InputEventPayload exists in the record
        if record.InputEventPayload.Payload != nil {
            tmp, err := json.Marshal(record.InputEventPayload.Payload)
            if err != nil {
                panic(err) // handle the error properly in your code
            }
            var event EventPayload
            if err := json.Unmarshal(tmp, &event); err != nil {
                panic(err) // handle the error properly in your code
            }
            fmt.Println(event)
        }
    }

Лучше было бы напрямую использовать правильную структуру, которую, как вы упомянули, вы не можете сделать:

type HubEvent struct {
    Time    string        `json:"time"`
    Payload *EventPayload `json:"payload"`
}

Чтобы предложить лучшие решения, нам может потребоваться больше узнать о вашей проблеме и о том, почему структура такая, какая она есть, и ее нельзя изменить.

Это решило проблему. Спасибо @eik!

Anirudh Garg 05.07.2024 12:15

Другие вопросы по теме