douxuan1284 2018-11-08 23:57
浏览 16
已采纳

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

I'm developing a tool that can be implemented to simplify the process of creating simple CRUD operations/endpoints. Since my endpoints don't know what kind of struct they'll be receiving, I've created an interface that users can implement, and return an empty object to be filled.

type ItemFactory interface {
    GenerateEmptyItem() interface{}
}

And the users would implement something like:

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

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

When the Test object gets created, its type is "Test", even though the func returned an interface{}. However, as soon as I try to unmarshal some json of the same format into it, it strips it of its type, and becomes of type "map[string]interface {}".

item := h.ItemFactory.GenerateEmptyItem()

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

fmt.Println(reflect.TypeOf(item))

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

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

Func that unmarshalls 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
}

Any suggestions as to why this happens, or how I can work around it?

Thanks

  • 写回答

1条回答 默认 最新

  • duanchen7036 2018-11-09 01:29
    关注

    Your question lacks an example showing this behavior so I'm just guessing this is what is happening.

    func Generate() interface{} {
        return Test{}
    }
    
    func GeneratePointer() interface{} {
        return &Test{}
    }
    
    func main() {
    
        vi := Generate()
        json.Unmarshal([]byte(`{}`), &vi)
        fmt.Printf("Generate Type: %T
    ", vi)
    
        vp := GeneratePointer()
        json.Unmarshal([]byte(`{}`), vp)
        fmt.Printf("GenerateP Type: %T
    ", vp)
    }
    

    Which outputs:

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

    I suggest you return a pointer in GenerateEmptyItem() instead of the actual struct value which is demonstrated in the GenerateP() example.

    Playground Example

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢
  • ¥15 不小心不正规的开发公司导致不给我们y码,
  • ¥15 我的代码无法在vc++中运行呀,错误很多
  • ¥50 求一个win系统下运行的可自动抓取arm64架构deb安装包和其依赖包的软件。
  • ¥60 fail to initialize keyboard hotkeys through kernel.0000000000
  • ¥30 ppOCRLabel导出识别结果失败
  • ¥15 Centos7 / PETGEM
  • ¥15 csmar数据进行spss描述性统计分析
  • ¥15 各位请问平行检验趋势图这样要怎么调整?说标准差差异太大了
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题