dongqia3502 2018-09-07 06:06 采纳率: 100%
浏览 284
已采纳

如何在mapstructure.decode中传递结构字段的指针

I am trying to decode a map into a struct type with help of mapstructure library. If I do it with plain variable it decodes ok, but if I pass struct field it does not decode the map:

package main

import (
    "github.com/mitchellh/mapstructure"
)

type Person struct {
    Name string
}

type Bundle struct {
    Name string
    Struct interface{}
}

func main() {
    p_map := map[string]string{
        "Name": "John",
    }

    p := Person{}
    mapstructure.Decode(p_map, &p)

    print(p.Name) // shows name John

    b := Bundle{
        "person"
        Person{},
    }

    mapstructure.Decode(p_map, &b.Struct)

    print(b.Struct.(Person).Name) // Does not show any name. Blank

}

Could you please clarify if I am passing wrong storage for map decoding or it is just mapstructure limitation and I am not able to decode maps into struct fields? Thank you!

UPD

I am sorry if I was not clear enough about the actual reason I need to use such flow:

I send HTTP requests to different resources and get various objects with different fields so initially I collect them as interface{}. After I get a particular resource object, I need to convert it into a particular struct (Person in my sample) so I use mapstructure.decode() function for that.

As I have various objects that are decoded in different structures I want to create a loop in order to avoid code duplication. What I wanted to do is to create a slice with different structures like:

bundles := []Bundle{
    {"person", Person{}}
    {"employee", Employee{}}
    ...
}

And then decode objects in a loop:

for bundle := range bundles {
    // map_storage contains different type maps that are going to be decoded into struct and key for the specific object is bundle name
    mapstructure.Decode(maps_storage[bundle.Name], &bundle.Struct)

    // bundle.Struct blank, but I expect that it is filled as in the example below
}
  • 写回答

2条回答 默认 最新

  • douben7260 2018-09-07 08:22
    关注

    I think you must slightly change the implementation

    var p1 Person
    
    mapstructure.Decode(p_map, &p1)
    b := Bundle{
        p1,
    }
    
    print(b.Struct.(Person).Name) // John will appear
    

    I'm trying your code above but lead to empty Person. Maybe Decode function cannot change real value of b.Struct(I'm not sure the exact reason, this is just my opinion), but if I decode to struct Person first then assign to Bundle that works.

    Updated: with some research, I found out the problem.You must use pointer instead of struct. here the updated code

    package main
    
    import (
        "github.com/mitchellh/mapstructure"
    )
    
    type Person struct {
        Name string
    }
    
    type Bundle struct {
        Name   string
        Struct interface{}
    }
    
    func main() {
        p_map := map[string]string{
            "Name": "John",
        }
    
        p := &Person{}
        mapstructure.Decode(p_map, &p)
    
        print(p.Name) // shows name John
    
        b := Bundle{
            "person",
            &Person{},
        }
    
        mapstructure.Decode(p_map, &b.Struct)
    
        print(b.Struct.(*Person).Name) // Does not show any name. Blank
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看