在Go中解组为struct时的奇怪行为

时间:2018-11-08 23:57:32

标签: go unmarshalling

我正在开发一种工具,可以简化该工具的创建简单CRUD操作/端点的过程。由于我的端点不知道它们将接收哪种结构,因此我创建了一个用户可以实现的接口,并返回一个要填​​充的空对象。

type ItemFactory interface {
    GenerateEmptyItem() interface{}
}

用户将执行以下操作:

type Test struct {
    TestString string `json:"testString"`
    TestInt int `json:"testInt"`
    TestBool bool `json:"testBool"`
}

func (t Test) GenerateEmptyItem() interface{} {
    return Test{}
}

创建Test对象时,即使func返回了一个接口{},其类型也为“ Test”。但是,一旦我尝试将相同格式的json解组,它就会剥离其类型,并变成“ map [string] interface {}”类型。

item := h.ItemFactory.GenerateEmptyItem()

//Prints "Test"
fmt.Printf("%T\n", item)

fmt.Println(reflect.TypeOf(item))

err := ConvertRequestBodyIntoObject(r, &item)
if err != nil {...}

//Prints "map[string]interface {}"
fmt.Printf("%T\n", item)

解组项目的功能:

func ConvertRequestBodyIntoObject(request *http.Request, object interface{}) error {
    body, err := ioutil.ReadAll(request.Body)
    if err != nil {
        return err
    }

    // Unmarshal body into request object
    err = json.Unmarshal(body, object)
    if err != nil {
        return err
    }

    return nil
}

关于这种情况发生的任何建议,或者如何解决?

谢谢

1 个答案:

答案 0 :(得分:2)

您的问题缺少显示此行为的示例,因此我只是猜测这是正在发生的事情。

func Generate() interface{} {
    return Test{}
}

func GeneratePointer() interface{} {
    return &Test{}
}

func main() {

    vi := Generate()
    json.Unmarshal([]byte(`{}`), &vi)
    fmt.Printf("Generate Type: %T\n", vi)

    vp := GeneratePointer()
    json.Unmarshal([]byte(`{}`), vp)
    fmt.Printf("GenerateP Type: %T\n", vp)
}

哪个输出:

Generate Type: map[string]interface {}
GenerateP Type: *main.Test

我建议您在GenerateEmptyItem()中返回一个指针,而不是在GenerateP()示例中演示的实际结构值。

Playground Example