Поскольку я часто отменял маршализацию http.Response.Body
, я подумал, что мог бы написать функцию, которая обрабатывает все трудности чтения, закрытия и демаршалирования в различные структуры.Вот почему я ввел функцию func unmarhalInterface(closer *io.ReadCloser, v *interface{}) error
и затем могу утверждать возвращаемое значение с помощью t:=i.(T)
.
Согласно этому ответу я уже обернул его в значение типа *interface{}
,но поскольку перекрывающим типом является interface{}
, а не myStruct
, реализация пакета json
выбирает map[string]interface{}
.После этого утверждение типа не выполняется (конечно).Есть ли что-то, чего я пропускаю, или требует, чтобы в этой реализации было утверждение типа «вручную», это означает, что ищите все поля на карте и присваивайте те, которые мне нужны, в моей структуре.
В приведенном ниже коде есть минимальный пример с нотациейв комментариях.Если моего объяснения недостаточно, пожалуйста, спросите.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
)
type myStruct struct {
A string `json:"a"`
B string `json:"b"`
}
func main() {
jsonBlob := []byte(`{"a":"test","b":"test2"}`)
var foo = interface{}(myStruct{})
closer := ioutil.NopCloser(bytes.NewReader(jsonBlob))
err := unmarshalCloser(&closer, &foo)
if err != nil {
log.Fatal(err)
}
fmt.Println(fmt.Sprintf("%v", foo))
// That´s what i want:
foo2 := foo.(myStruct)
fmt.Println(foo2.A)
}
func unmarshalCloser(closer *io.ReadCloser, v *interface{}) error {
defer func() { _ = (*closer).Close() }()
data, err := ioutil.ReadAll(*closer)
if err != nil {
return err
}
err = json.Unmarshal(data, v)
if err != nil {
return err
}
return nil
}
Детская площадка Голанга