Можно ли делать динамические c маршалинг структур в Go? - PullRequest
0 голосов
/ 16 февраля 2020

У меня есть несколько избыточных логи c Я извлекаю в утилиту для привязки запросов к структурам, и я надеялся, что смогу как-нибудь сделать это динамически. То, что я хочу, это в основном привязать любой запрос к типу структуры, который я передаю. Это значительно уменьшит некоторый код в моей программе.

Я мог бы иметь структуру Task, или я мог бы иметь Information STRUCT. Вся эта информация поступает на сервер через JSON, но я хочу иметь возможность передавать имя типа и автоматически связывать его, чтобы уменьшить код, который я пишу.

Пример Caller

func StoreTask(dbWrapper *database.DB) func(http.ResponseWriter, *http.Request) {
    return func(rw http.ResponseWriter, r *http.Request) {
        data := &utilities.DynamicStruct{entities.Task, r, rw}
        utilities.PersistRequest(data)
    }
}

Вот мой маленький пример:

type DynamicStruct struct {
    cType  interface{}
    writer http.ResponseWriter
    req    *http.Request
}

func PersistRequest(s *DynamicStruct, decoderOpts *DecoderMetadata) {
    r := s.req
    rw := s.writer

    // I want the struct to basically be able to take any type 
    data := s.cType

    err := r.ParseForm()
    if err != nil {
        log.Printf("HTTP %d - %s", 500, err.Error())
        http.Error(rw, err.Error(), 500)
    }

    // This is where the dynamic nature of the param would come into play that I'm looking for..
    newTask := new(data)

    decoder := utilities.GenerateDecoder(decoderOpts)

    // Using gorilla/schema here
    err = decoder.Decode(newTask, r.Form)

    if err != nil {
        log.Printf("HTTP %d - %s", 500, err.Error())
        http.Error(rw, err.Error(), 500)
    }

    rw.Header().Set("Content-Type", "application/json")
    json.NewEncoder(rw).Encode(newTask)


}

1 Ответ

2 голосов
/ 16 февраля 2020

Когда вы выполняете маршалинг или декодируете неизвестную структуру, подобную этой, вам ничего больше не нужно делать: просто передайте значение интерфейса кодировщику, и он будет кодировать базовое значение, используя отражение, или вызовите MashalJSON если он реализует пользовательский маршалер.

dynamicStruct.cType=someStructValue

Если вы демаршалируете, вы можете сделать то же самое, передав указатель на структуру:

dynamicStruct.cType=&SomeStruct{}

Тогда вам не нужно чтобы создать новый экземпляр неизвестного типа, просто передайте интерфейс unmarshal.

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