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

报告相同问题?

悬赏问题

  • ¥30 YOLO检测微调结果p为1
  • ¥20 求快手直播间榜单匿名采集ID用户名简单能学会的
  • ¥15 DS18B20内部ADC模数转换器
  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题