Go: динамическая структура структуры - PullRequest
2 голосов
/ 03 мая 2019

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

У меня есть структура, которая представляет данные для сериализации как часть ответа JSON. Свойство этой структуры config может быть одной из трех возможных структур, однако единственный способ, которым я знаю, чтобы представить это, - это использовать тип interface{} и заставить вызывающий тип утверждать свойство.

type Response struct {
    Field1 string      `json:"field1"`
    Field2 int         `json:"field2"`
    Config interface{} `json:"config"`
}

type ConfigOne struct {
    SomeField string
}

type ConfigTwo struct {
    SomeField int
}

type ConfigThree struct {
    SomeField bool
}

Тогда у меня могут быть функции стиля New для создания нужного мне экземпляра:

func NewConfigTwo() *Response {
    return &Response{
        Field1: "hello",
        Field2: 1,
        Config: ConfigTwo{
            SomeField: 22,
        },
    }
}

Есть ли лучший способ представить поле со структурами типа enum? Или это так хорошо, как я могу это сделать?

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

1 Ответ

2 голосов
/ 03 мая 2019

По сути, вы пытаетесь реализовать алгебраический тип данных здесь. Чтобы расширить комментарий @ mkopriva, взгляните на этот пост: Go и алгебраические типы данных . По сути, вы указываете непустой интерфейс, так что все возможные типы реализуют метод, а другие не удовлетворяют интерфейс «случайно» (тогда как каждый тип реализует interface{}), а затем используете переключатели типов.

Что-то вроде (не проверено):

type Response struct {
    Field1 string      `json:"field1"`
    Field2 int         `json:"field2"`
    Config Configable  `json:"config"`
}

type Configable interface {
    isConfig()
}

type ConfigOne struct {
    SomeField string
}

func (ConfigOne) isConfig() {}

// ... and so on for other Config* types
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...