如何在Golang中解组反射值

huangapple go评论107阅读模式
英文:

How to unmarshal a reflect.Value in Golang

问题

我得到了这个测试

  1. func (t *DeviceTests) CreatePublicDevice() {
  2. registerRegularDevice := tester.TableTest{
  3. Method: "POST",
  4. Path: "/iot/devices",
  5. Status: http.StatusOK,
  6. Name: "CreatePublicDevice",
  7. Description: "register Regular Device has to return 200",
  8. Body: PublicDevice,
  9. }
  10. resp := registerRegularDevice.DoubleSpin(t.Test)
  11. log.Println(resp.(types.Device).ID)
  12. }

我想将这部分代码放在一个单独的包中,这样我就可以在不同的项目中重用。

  1. func (test TableTest) DoubleSpin(t *testing.T) interface{} {
  2. actualBody := test.innnerSpin(t)
  3. log.Print(string(actualBody))
  4. thetype := reflect.TypeOf(test.Body)
  5. log.Println(thetype)
  6. receivedev := reflect.Zero(thetype)
  7. err := json.Unmarshal(actualBody, receivedev.Interface())
  8. assert.NoError(t, err)
  9. log.Println(receivedev)
  10. return receivedev.Interface()
  11. }

日志显示:

  1. 2016/11/06 16:54:01 {"id":"581f7c49b2c79a543c627474","hostname":"Shriekersolar","alias":"my PublicDevice","channels":8,"owner":"public","location":{}}
  2. 2016/11/06 16:54:01 types.Device
  3. 2016/11/06 16:54:01 {ObjectIdHex("") 0 map[]}
  4. 2016/11/06 16:54:01 ObjectIdHex("")

设备的结构如下:

  1. type Device struct {
  2. ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
  3. Hostname string `json:"hostname"`
  4. Alias string `json:"alias"`
  5. Channels int `json:"channels"`
  6. Owner string `json:"owner"`
  7. Location map[string]string `json:"location"`
  8. }
英文:

I got this test

  1. func (t *DeviceTests) CreatePublicDevice() {
  2. registerRegularDevice := tester.TableTest{
  3. Method: "POST",
  4. Path: "/iot/devices",
  5. Status: http.StatusOK,
  6. Name: "CreatePublicDevice",
  7. Description: "register Regular Device has to return 200",
  8. Body: PublicDevice,
  9. }
  10. resp := registerRegularDevice.DoubleSpin(t.Test)
  11. log.Println(resp.(types.Device).ID)
  12. }

I want to keep this in a separate package so I can reuse on diferent projects.

  1. func (test TableTest) DoubleSpin(t *testing.T) interface{} {
  2. actualBody := test.innnerSpin(t)
  3. log.Print(string(actualBody))
  4. thetype := reflect.TypeOf(test.Body)
  5. log.Println(thetype)
  6. receivedev := reflect.Zero(thetype)
  7. err := json.Unmarshal(actualBody, receivedev.Interface())
  8. assert.NoError(t, err)
  9. log.Println(receivedev)
  10. return receivedev.Interface()
  11. }

Logs say:

  1. 2016/11/06 16:54:01 {"id":"581f7c49b2c79a543c627474","hostname":"Shriekersolar","alias":"my PublicDevice","channels":8,"owner":"public","location":{}}
  2. 2016/11/06 16:54:01 types.Device
  3. 2016/11/06 16:54:01 {ObjectIdHex("") 0 map[]}
  4. 2016/11/06 16:54:01 ObjectIdHex("")

Where a device looks like:

  1. type Device struct {
  2. ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
  3. Hostname string `json:"hostname"`
  4. Alias string `json:"alias"`
  5. Channels int `json:"channels"`
  6. Owner string `json:"owner"`
  7. Location map[string]string `json:"location"`
  8. }

答案1

得分: 5

使用reflect.New而不是reflect.Zero来获取指针:

  1. thetype := reflect.TypeOf(i)
  2. receivedev := reflect.New(thetype)
  3. err := json.Unmarshal(actualBody, receivedev.Interface())
  4. if err != nil {
  5. panic(err)
  6. }

Playground: https://play.golang.org/p/pGXRWpBFiF.

英文:

Use reflect.New rather than reflect.Zero to get a pointer:

  1. thetype := reflect.TypeOf(i)
  2. receivedev := reflect.New(thetype)
  3. err := json.Unmarshal(actualBody, receivedev.Interface())
  4. if err != nil {
  5. panic(err)
  6. }

Playground: https://play.golang.org/p/pGXRWpBFiF.

huangapple
  • 本文由 发表于 2016年11月7日 03:02:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/40453298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定