首页 > 解决方案 > 在 Go 中解组到结构时的奇怪行为

问题描述

我正在开发一种可以实施的工具,以简化创建简单 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 对象被创建时,它的类型是“Test”,即使函数返回了一个 interface{}。但是,一旦我尝试将一些相同格式的 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
}

关于为什么会发生这种情况或我如何解决它的任何建议?

谢谢

标签: gounmarshalling

解决方案


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

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()

游乐场示例


推荐阅读