去Unmarshal嵌套未知领域 [英] Go Unmarshal nested unknown fields

查看:96
本文介绍了去Unmarshal嵌套未知领域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为此分配了一个伟大的项目 ,并拥有刚刚一直在学习一些去了一个混乱。我无法弄清的问题是关于自定义解组的一些问题,如果您看到这里你可以看到这个解组包含 Thing struct,它包含一个数据接口{} 字段,然后使用 Kind字符串字段取消编组。除嵌套情况外,这一切都很好。所以最好的例子是:

只要说你有 Thing 结构就是一个列表,因此 Thing.Data 将被解组,以便列出。然后列表有3 <类型为 link 的孩子在 Children [] Thing 字段中。这些孩子最终成为 map [string] interface {} 这是我的问题。我怎么能通过嵌套数据来解决这个问题?这样 Children.Data 也被解组。有没有办法做到这一点,或者我将不得不写一个大循环或递归算法?请让我知道你的想法,或者如果我看到这种情况都是错误的。谢谢

更新
这是一个json示例



<$ p $
kind:Listing,
data:{
after:null,
dist:10,
facets:{},
modhash:null,
whitelist_status:all_ads,
children:[
{
kind:t3,
data:{
domain:self.nanocurrency,
approved_at_utc:null,
mod_reason_by: null,
banned_by:null,
num_reports:null,
subreddit_id:t5_2wlj3,
thumbnail_width:null,
subreddit :CryptoCurrency,
selftext_html:null,
selftext:,
likes:null,
suggested_sort:null ,
crosspost_parent_list:[
{
domain:self.nanocurrency,
approved_at_utc:null,
mod_reason_by:null,
banned_by:null,
num_reports:null,
subreddit_id:t5_4br49,
thumbnail_width:null,
subreddit: nanocurrency,
selftext_html:& lt;! - SC_OFF - & gt;& lt; div class = \md\& gt;& lt; p& gt;看到很多关于协议中缺少时间戳的评论,并且只是想提供一些信息,说明为什么客观准确的全球时间戳是分散系统中的错觉。另一方面,逻辑时间是可以实现的,事实上Nano是通过单独的块链和有向非循环图(DAG)实现的。 & lt; / p& gt; \\\
\\\
& lt; p& gt;通常,在分散的分布式系统中,只有逻辑时间(C发生在B发生在A之后)可以在全局上达成一致Lamport时间:& lt; a href = \https://amturing.acm.org/p558-lamport.pdf\& gt; https://amturing.acm.org/p558-lamport.pdf& ; lt; / a& gt;或矢量时钟)。这就是纳米分类帐通过链接块来完成的任务,就像任何其他区块链一样。然后它通过DAG连接这些链。将全球时间同步到逻辑时间是一个棘手的问题,可以通过易于发生sybil攻击的共识方法,通过大多数区块链使用的概率方法 - 基本上依赖于同行 - 或者像NTP这样的集中方法来解决这是一个分权体系中的禁区。如果您对此感兴趣,请检查本文:& lt; a href = \http://soft.vub.ac.be/%7Etvcutsem/distsys/clocks.pdf\& gt; http://soft.vub.ac。 be /〜tvcutsem / distsys / clocks.pdf& lt; / a& gt;& lt; / p& gt; \ n \ n& lt; p& gt;因此,您要做的是什么遇到的问题是,尽管理论上纳米或比特币或以太坊网络中的所有节点或相关子节点都可以同意呼叫某个时间&2018年2月12日星期一20:35:23 ,这个时间戳可能仍然与外部世界不正确。& lt; / p& gt; \\\
\\\
& lt; p& gt;这就是为什么当今软件中有准确的全球时间戳依靠集中信息和可信实体。唯一可以改变的方法是机器开始准确地设置自己的时钟(例如芯片级原子钟)< / p& gt; \\ n& lt; p& gt;有些人认为对于Nano来说这是个坏消息,因为在传统区块链中,时间戳相当重要,因为它们被用于新块验证:& lt; a href = \http://culubas.blogspot.co.uk/2011/05/ timejacking-bitcoin_802.html\&安培; GT; HTTP://culubas.blogspot.co.uk/2011/05/timejacking-bitcoin_802.html& LT; / A&安培; GT; 。时间戳在区块链中同时是一种祝福和诅咒:它们允许对时间段进行计时和验证,并因此调节硬币挖掘,但也允许时间戳双重攻击。 < / p& gt; \\\
\\\
& lt; p& gt;即使比特币中的时间戳和时间戳的相对重要性,时间戳在比特币中并不能保证与链上的逻辑时间相对应。这里是关于比特币块时间戳的比特币wiki:& lt; a href = \https://en.bitcoin.it/wiki/Block_timestamp\& gt; https: //en.bitcoin.it/wiki/Block_timestamp&lt;/a&gt; & lt; / p& gt; \\\
\\\
& lt; blockquote& gt; \\\
& lt; p& gt;如果时间戳大于前面11个块的中值时间戳,并且少于网络调整时间+ 2小时。 & amp; amp; amp; quot;网络调整时间& amp; amp; amp; amp; quot;是连接到您的所有节点返回的时间戳的中位数。因此,块时间戳不完全准确,甚至不需要按顺序排列。阻滞时间仅在一两个小时内准确。 & lt; / p& gt; \\\
& lt; / blockquote& gt; \\\
\\\
& lt; p& gt;这可能是一样好。尽管如此,仍然没有订单保证,而且还有一再被讨论过的攻击的可能性。比特币代码中有一些警卫来防止这些事情发生。 & lt; / p& gt; \\\
\\\
& lt; p& gt;因此,如果您有人在讲授体系结构优越的硬币如何具有准确且单调递增的时间戳,请将它们指向此处或这里: & lt; a href = \https://cointelegraph.com/news/timestamp-hacking-debunking-the-myth-of-precision-timestamps\& gt; https://cointelegraph.com/ news / timestamp-hacking-debunking-the -thth-of-precision-timestamps& lt; / a& gt;< / p& gt; \\\
\\\
& lt; p& gt;时间戳是方便有协议?是的,这可能是包含它们的一个很好的理由。时间戳准确地描述了全球时间,并且它们可以用作任何链条的证据吗?没有,他们可以&#39; t& lt; / p& gt; \\\
\\\
& lt; p& gt;为什么我们会在资源管理器中看到不准确的时间戳? & lt; / p& gt; \\\
\\\
& lt; p& gt;为什么人们喜欢在分类帐之外的分贝中保存数据,并且已设置为1月19日。唠叨这是Nano的弱点吗? < / p& gt; \\\
& lt; / div& gt;& lt;! - SC_ON - & gt;,
selftext:看到很多关于协议中缺少时间戳的评论,并且只是想提供一些信息,说明为什么客观准确的全球时间戳是分散式系统中的错觉。另一方面,逻辑时间是可以实现的,事实上Nano是通过单独的块链和有向非循环图(DAG)实现的。通常,在分散的分布式系统中,只有逻辑时间(C发生在B发生在A之后)可以在全球达成一致(例如Lamport时间:https://amturing.acm.org/p558-lamport。 pdf或矢量时钟)。这就是纳米分类帐通过链接块进行的操作,就像任何其他区块链一样。然后它通过DAG连接这些链。将全球时间同步到逻辑时间是一个棘手的问题,可以通过易于发生sybil攻击的共识方法,通过大多数区块链所采用的概率方法 - 主要依赖于其同行 - 或者像NTP这样的集中方法来解决这是一个分权体系中的禁区。如果您有兴趣,请检查例如本文:http://soft.vub.ac.be/~tvcutsem/distsys/clocks.pdf\\\
\所以你遇到的问题是,虽然理论上所有或相关的子集的节点纳米或比特币或以太坊网络可能同意打电话给特定时间2018年2月12日星期一20:35:23,这个时间戳可能仍然与外部世界不正确。这就是为什么准确的全球性当今软件中的时间戳依赖于集中信息和可信实体。这可以改变的唯一方法是机器开始准确地设置自己的时钟(例如芯片级原子钟)\\ n \\ n有些人认为这对纳米来说是个坏消息,因为在传统区块链中,时间戳是相当重要的,因为它们用于新块验证:http://culubas.blogspot.co.uk/2011/05/timejacking-bitcoin_802.html。时间戳在区块链中同时是一种祝福和诅咒:它们允许对时间段进行计时和验证,并因此调节硬币挖掘,但也允许时间戳双重攻击。由于Nano不使用挖掘,因此不容易受到这些攻击。尽管比特币的时间戳和时间戳的相对重要性,但比特币中的时间戳并不能保证与链上的逻辑时间相对应。以下是讨论比特币区块时间戳的比特币维基:https://en.bitcoin.it/wiki/Block_timestamp \\\
\\\
& gt;如果时间戳大于前面11个块的中间时间戳,并且小于网络调整时间+2小时,则该时间戳被接受为有效。 \网络调整时间\\是所有连接到您的节点返回的时间戳的中位数。因此,块时间戳不完全准确,甚至不需要按顺序排列。阻滞时间仅在一两个小时内准确。 \\ \\ \\ \\ \\ \\ \\这可能是一样好。尽管如此,仍然没有订单保证,而且还有一再被讨论过的攻击的可能性。比特币代码中有一些警卫来防止这些事情发生。 \\ n因此,如果您有人教您关于建筑上优越的硬币如何具有准确且单调增加的时间戳的信息,请将它们指向此处或以下地址:https://cointelegraph.com/news/timestamp-hacking-debunking-the - 精密时间戳的准确性时间戳可以方便地使用协议?是的,这可能是包含它们的一个很好的理由。时间戳准确地描述了全球时间,并且它们可以用作任何链条的证据吗?不,他们不能。为什么我们在块浏览器中看到不准确的时间戳?因为这些数据保存在分类帐外的数据库中,并且已在1月19日设置。没有其他更多的了。 ,
likes:null,
suggested_sort:null,
user_reports:[],
secure_media:null,
is_reddit_media_domain:false,
link_flair_text:null,
id:7ww6bm,
banned_at_utc:null,
mod_reason_title:null,
view_count:null,
archived:false,
clicked:false,
media_embed:{},
report_reasons:null,
作者:ohlookaballoon,
num_crossposts:2,
保存:false,
mod_reports:[],
can_mod_post:false,
is_crosspostable:true,
pinned:false,
score:24,
approved_by:null,
over_18:false,
hidden:false,
thumbnail:self,
edited:false,
link_flair_css_class:null,
author_flair_css_class:null,
contest_mode:false,
gilded:0,
downs:0,
brand_safe:false,
secure_media_embed:{},
removal_reason:null,
author_flair_text:null,
stickied:false,
can_gild:true,
thumbnail_height:null,
parent_whitelist_status:null,
name:t3_7ww6bm,
spoiler:false,
permalink:/ r / nanocurrency / comments / 7ww6bm / why_global_time_objectively_accurate_timestamps /,
subreddit_type:public,
locked: false,
hide_score:false,
created:1518417258,
url:https://www.reddit.com/r/nanocurrency/comments/7ww6bm/why_global_time_objectively_accurate_timestamps /,
whitelist_status:null,
quarantine:false,
title:为什么是全球时间,客观准确的时间戳ps在分散系统中无法实现,
created_utc:1518388458,
subreddit_name_prefixed:r / nanocurrency,
ups:24,
media :null,
num_comments:18,
is_self:true,
visited:false,
mod_note:null,
is_video :false,
distinguished:null
}
],
user_reports:[],
secure_media:null,
is_reddit_media_domain :false,
link_flair_text:null,
id:7x3r45,
banned_at_utc:null,
mod_reason_title:null,
view_count:null,
archived:false,
clicked:false,
media_embed:{},
report_reasons:null,
author:ohlookaballoon,
num_crossposts:0,
saved:false,
mod_reports:[],
can_mod_post:false,
is_crosspostable:true,
pinned:false,
score:2,
approved_by:null,
over_18:false,
hidden:false,
thumbnail:default,
edited:false,
link_flair_css_class:null,
author_flair_css_class: 新,
contest_mode:false,
镀金:0,
下降:0,
brand_safe:true,
secure_media_embed:{},
removal_reason:null,
author_flair_text:Redditor for ,
stickied:false,
can_gild:true,
thumbnail_height:null,
parent_whitelist_status:all_ads,
name:t3_7x3r45,
crosspost_parent:t3_7ww6bm,
spoiler:false,
permalink:/ r / CryptoCurrency / comments / 7x3r45 / why_global_time_objectively_accurate_timestamps /,
subreddit_type:public,
locked:false,
hide_score:false,
created:1518496223,
网址:https://np.reddit.com/r/nanocurrency/comments/7ww6bm/wh y_global_time_objectively_accurate_timestamps /,
whitelist_status:all_ads,
quarantine:false,
title:为什么全球时间,客观准确的时间戳在分散系统中无法实现,
created_utc:1518467423,
subreddit_name_prefixed:r / CryptoCurrency,
ups:2,
media:null,
num_comments :0,
is_self:false,
visited:false,
mod_note:null,
is_video:false,
:null
}
},


解决方案

这正是 json.RawMessage 的目的所在(请看文档中的解组示例)。首先解组JSON对象的顶层,检查kind字段,然后解组数据字段:

  type列表struct { 
WhitelistStatus字符串`json:whitelist_status`
Children [] Thing`json:children`
}

type T3 struct {
Domain
CrosspostParentList [] struct {
域名字符串`json:domain`
}`json:crosspost_parent_list`
}

类型结构{
种类字符串`json:kind`
数据接口{}`json:data`
}

func(t * Thing)UnmarshalJSON(b []字节)错误{
var step1 struct {
种类字符串`json:kind`
Data json.RawMessage`json:data`
}

if err:= json.Unmarshal(b,& step1); err!= nil {
return err
}

var step2接口{}
切换step1.Kind {
caseListing:
step2 =& Listing {}
caset3:
step2 =& T3 {}
default:
return errors.New(unknown kind:+ step1 .Kind)//或者简单地忽略
}

if err:= json.Unmarshal(b,step2); err!= nil {
return err
}

t.Kind = step1.Kind
t.Data = step2

return nil
}

在操场上试试: https://play.golang.org/p/giBVT2IWPd-


I forked a great project here, and have just been having a mess around with it learning some go. My issue I can't figure out is some things about custom unmarshaling, if you see here you can see this unmarshals the Thing struct which holds a Data interface{} field that is then unmarshalled using the Kind string field. This all works great except the nested situations. So the best thing is an example:

Just say you have Thing struct that's kind is a listing, thus the Thing.Data this is unmarshalled to type listing. Then listing has 3 Children of type link that is held in the Children []Thing field. These Children end up being of type map[string]interface {} which is my issue. How can I have this unmarshall down through nested data? So that the Children.Data is also unmarshalled. Is there a way to do this in go or will I have to write a big loop or recursion algorithm? Please let me know what you think or if I am looking at this situation all wrong. Thank you

UPDATE Here is a json sample

{
    "kind": "Listing",
    "data": {
        "after": null,
        "dist": 10,
        "facets": {},
        "modhash": null,
        "whitelist_status": "all_ads",
        "children": [
            {
                "kind": "t3",
                "data": {
                    "domain": "self.nanocurrency",
                    "approved_at_utc": null,
                    "mod_reason_by": null,
                    "banned_by": null,
                    "num_reports": null,
                    "subreddit_id": "t5_2wlj3",
                    "thumbnail_width": null,
                    "subreddit": "CryptoCurrency",
                    "selftext_html": null,
                    "selftext": "",
                    "likes": null,
                    "suggested_sort": null,
                    "crosspost_parent_list": [
                        {
                            "domain": "self.nanocurrency",
                            "approved_at_utc": null,
                            "mod_reason_by": null,
                            "banned_by": null,
                            "num_reports": null,
                            "subreddit_id": "t5_4br49",
                            "thumbnail_width": null,
                            "subreddit": "nanocurrency",
                            "selftext_html": "&lt;!-- SC_OFF --&gt;&lt;div class=\"md\"&gt;&lt;p&gt;Seeing lots of comments about the lack of timestamps in the protocol, and just wanted to provide some information on why objectively accurate, global time timestamps are an illusion in decentralized systems. Logical time on the other hand is achievable and is in fact achieved in Nano via the individual block chains and the directed, acyclic graph (DAG). &lt;/p&gt;\n\n&lt;p&gt;Generally, in a decentralized, distributed system, only logical time (C happened after B happened after A) can be agreed on globally (e.g. Lamport time: &lt;a href=\"https://amturing.acm.org/p558-lamport.pdf\"&gt;https://amturing.acm.org/p558-lamport.pdf&lt;/a&gt; or vector clocks). This is what the nano ledger does via chaining blocks, just as any other blockchain. Then it connects those chains via a DAG. Syncing global time to logical time is a hard problem that can either be approached via a consensus approach which is prone to sybil attacks, via a probabilistic approach which is what most blockchains go with - essentially relying on their peers - or a centralized approach like NTP which is a no-go in a decentralized system. If you&amp;#39;re interested, check e.g. this paper: &lt;a href=\"http://soft.vub.ac.be/%7Etvcutsem/distsys/clocks.pdf\"&gt;http://soft.vub.ac.be/~tvcutsem/distsys/clocks.pdf&lt;/a&gt;&lt;/p&gt;\n\n&lt;p&gt;So what you&amp;#39;re running into is the problem that while theoretically all or a relevant subset of nodes within the Nano or Bitcoin or Ethereum network could agree to call a certain time &amp;quot;Monday February 12 2018 20:35:23&amp;quot;, this timestamp could still be incorrect vs the outside world.&lt;/p&gt;\n\n&lt;p&gt;That&amp;#39;s why any accurate global timestamps in software today rely on centralized information and trusted entities. The only way this can change is if machines start setting their clocks on their own accurately (e.g. chip-scale atomic clocks)&lt;/p&gt;\n\n&lt;p&gt;Some people think this is bad news for Nano because in traditional blockchain, timestamps are fairly important because they are used in new block validation: &lt;a href=\"http://culubas.blogspot.co.uk/2011/05/timejacking-bitcoin_802.html\"&gt;http://culubas.blogspot.co.uk/2011/05/timejacking-bitcoin_802.html&lt;/a&gt; . Timestamps are a blessing and a curse at the same time in blockchain: They allow for timing and validation of blocks and therefore regulation of coin mining, but also allow for timestamp double spend attacks. Since Nano does not use mining, it is not susceptible to those attacks.&lt;/p&gt;\n\n&lt;p&gt;Even with the relative importance of time and timestamps in Bitcoin, timestamp in Bitcoin are not guaranteed to be corresponding to logical time on the chain. Here&amp;#39;s the bitcoin wiki talking about the bitcoin block timestamp: &lt;a href=\"https://en.bitcoin.it/wiki/Block_timestamp\"&gt;https://en.bitcoin.it/wiki/Block_timestamp&lt;/a&gt; &lt;/p&gt;\n\n&lt;blockquote&gt;\n&lt;p&gt;A timestamp is accepted as valid if it is greater than the median timestamp of previous 11 blocks, and less than the network-adjusted time + 2 hours. &amp;quot;Network-adjusted time&amp;quot; is the median of the timestamps returned by all nodes connected to you. As a result, block timestamps are not exactly accurate, and they do not even need to be in order. Block times are accurate only to within an hour or two. &lt;/p&gt;\n&lt;/blockquote&gt;\n\n&lt;p&gt;This is probably as good as it gets. Still no ordering guarantees though, and a possibilities for attacks which have been discussed again and again. There are certain guards in Bitcoin code to prevent these from happening. &lt;/p&gt;\n\n&lt;p&gt;So if you have somebody lecturing you about how architecturally superior coins would have a accurate and monotonically increasing timestamps, point them here, or here: &lt;a href=\"https://cointelegraph.com/news/timestamp-hacking-debunking-the-myth-of-precision-timestamps\"&gt;https://cointelegraph.com/news/timestamp-hacking-debunking-the-myth-of-precision-timestamps&lt;/a&gt;&lt;/p&gt;\n\n&lt;p&gt;Would timestamps be convenient to have on the protocol? Yes, and that would likely be a good reason to include them. Are timestamps accurately depicting global time, and can they be used as evidence in any chain? No they can&amp;#39;t.&lt;/p&gt;\n\n&lt;p&gt;Why are we seeing inaccurate timestamps in the block explorer? Because these are kept in a db outside of the ledger and have been set January 19. Nothing more to it.&lt;/p&gt;\n\n&lt;p&gt;Why do people like to babble about how this is a weakness in Nano? No clue.&lt;/p&gt;\n&lt;/div&gt;&lt;!-- SC_ON --&gt;",
                            "selftext": "Seeing lots of comments about the lack of timestamps in the protocol, and just wanted to provide some information on why objectively accurate, global time timestamps are an illusion in decentralized systems. Logical time on the other hand is achievable and is in fact achieved in Nano via the individual block chains and the directed, acyclic graph (DAG). \n\nGenerally, in a decentralized, distributed system, only logical time (C happened after B happened after A) can be agreed on globally (e.g. Lamport time: https://amturing.acm.org/p558-lamport.pdf or vector clocks). This is what the nano ledger does via chaining blocks, just as any other blockchain. Then it connects those chains via a DAG. Syncing global time to logical time is a hard problem that can either be approached via a consensus approach which is prone to sybil attacks, via a probabilistic approach which is what most blockchains go with - essentially relying on their peers - or a centralized approach like NTP which is a no-go in a decentralized system. If you're interested, check e.g. this paper: http://soft.vub.ac.be/~tvcutsem/distsys/clocks.pdf\n\nSo what you're running into is the problem that while theoretically all or a relevant subset of nodes within the Nano or Bitcoin or Ethereum network could agree to call a certain time \"Monday February 12 2018 20:35:23\", this timestamp could still be incorrect vs the outside world.\n\nThat's why any accurate global timestamps in software today rely on centralized information and trusted entities. The only way this can change is if machines start setting their clocks on their own accurately (e.g. chip-scale atomic clocks)\n\nSome people think this is bad news for Nano because in traditional blockchain, timestamps are fairly important because they are used in new block validation: http://culubas.blogspot.co.uk/2011/05/timejacking-bitcoin_802.html . Timestamps are a blessing and a curse at the same time in blockchain: They allow for timing and validation of blocks and therefore regulation of coin mining, but also allow for timestamp double spend attacks. Since Nano does not use mining, it is not susceptible to those attacks.\n\nEven with the relative importance of time and timestamps in Bitcoin, timestamp in Bitcoin are not guaranteed to be corresponding to logical time on the chain. Here's the bitcoin wiki talking about the bitcoin block timestamp: https://en.bitcoin.it/wiki/Block_timestamp \n\n&gt; A timestamp is accepted as valid if it is greater than the median timestamp of previous 11 blocks, and less than the network-adjusted time + 2 hours. \"Network-adjusted time\" is the median of the timestamps returned by all nodes connected to you. As a result, block timestamps are not exactly accurate, and they do not even need to be in order. Block times are accurate only to within an hour or two. \n\nThis is probably as good as it gets. Still no ordering guarantees though, and a possibilities for attacks which have been discussed again and again. There are certain guards in Bitcoin code to prevent these from happening. \n\nSo if you have somebody lecturing you about how architecturally superior coins would have a accurate and monotonically increasing timestamps, point them here, or here: https://cointelegraph.com/news/timestamp-hacking-debunking-the-myth-of-precision-timestamps\n\nWould timestamps be convenient to have on the protocol? Yes, and that would likely be a good reason to include them. Are timestamps accurately depicting global time, and can they be used as evidence in any chain? No they can't.\n\nWhy are we seeing inaccurate timestamps in the block explorer? Because these are kept in a db outside of the ledger and have been set January 19. Nothing more to it.\n\nWhy do people like to babble about how this is a weakness in Nano? No clue.",
                            "likes": null,
                            "suggested_sort": null,
                            "user_reports": [],
                            "secure_media": null,
                            "is_reddit_media_domain": false,
                            "link_flair_text": null,
                            "id": "7ww6bm",
                            "banned_at_utc": null,
                            "mod_reason_title": null,
                            "view_count": null,
                            "archived": false,
                            "clicked": false,
                            "media_embed": {},
                            "report_reasons": null,
                            "author": "ohlookaballoon",
                            "num_crossposts": 2,
                            "saved": false,
                            "mod_reports": [],
                            "can_mod_post": false,
                            "is_crosspostable": true,
                            "pinned": false,
                            "score": 24,
                            "approved_by": null,
                            "over_18": false,
                            "hidden": false,
                            "thumbnail": "self",
                            "edited": false,
                            "link_flair_css_class": null,
                            "author_flair_css_class": null,
                            "contest_mode": false,
                            "gilded": 0,
                            "downs": 0,
                            "brand_safe": false,
                            "secure_media_embed": {},
                            "removal_reason": null,
                            "author_flair_text": null,
                            "stickied": false,
                            "can_gild": true,
                            "thumbnail_height": null,
                            "parent_whitelist_status": null,
                            "name": "t3_7ww6bm",
                            "spoiler": false,
                            "permalink": "/r/nanocurrency/comments/7ww6bm/why_global_time_objectively_accurate_timestamps/",
                            "subreddit_type": "public",
                            "locked": false,
                            "hide_score": false,
                            "created": 1518417258,
                            "url": "https://www.reddit.com/r/nanocurrency/comments/7ww6bm/why_global_time_objectively_accurate_timestamps/",
                            "whitelist_status": null,
                            "quarantine": false,
                            "title": "Why global time, objectively accurate timestamps are not achievable in decentralized systems",
                            "created_utc": 1518388458,
                            "subreddit_name_prefixed": "r/nanocurrency",
                            "ups": 24,
                            "media": null,
                            "num_comments": 18,
                            "is_self": true,
                            "visited": false,
                            "mod_note": null,
                            "is_video": false,
                            "distinguished": null
                        }
                    ],
                    "user_reports": [],
                    "secure_media": null,
                    "is_reddit_media_domain": false,
                    "link_flair_text": null,
                    "id": "7x3r45",
                    "banned_at_utc": null,
                    "mod_reason_title": null,
                    "view_count": null,
                    "archived": false,
                    "clicked": false,
                    "media_embed": {},
                    "report_reasons": null,
                    "author": "ohlookaballoon",
                    "num_crossposts": 0,
                    "saved": false,
                    "mod_reports": [],
                    "can_mod_post": false,
                    "is_crosspostable": true,
                    "pinned": false,
                    "score": 2,
                    "approved_by": null,
                    "over_18": false,
                    "hidden": false,
                    "thumbnail": "default",
                    "edited": false,
                    "link_flair_css_class": null,
                    "author_flair_css_class": "New",
                    "contest_mode": false,
                    "gilded": 0,
                    "downs": 0,
                    "brand_safe": true,
                    "secure_media_embed": {},
                    "removal_reason": null,
                    "author_flair_text": "Redditor for 27 days.",
                    "stickied": false,
                    "can_gild": true,
                    "thumbnail_height": null,
                    "parent_whitelist_status": "all_ads",
                    "name": "t3_7x3r45",
                    "crosspost_parent": "t3_7ww6bm",
                    "spoiler": false,
                    "permalink": "/r/CryptoCurrency/comments/7x3r45/why_global_time_objectively_accurate_timestamps/",
                    "subreddit_type": "public",
                    "locked": false,
                    "hide_score": false,
                    "created": 1518496223,
                    "url": "https://np.reddit.com/r/nanocurrency/comments/7ww6bm/why_global_time_objectively_accurate_timestamps/",
                    "whitelist_status": "all_ads",
                    "quarantine": false,
                    "title": "Why global time, objectively accurate timestamps are not achievable in decentralized systems",
                    "created_utc": 1518467423,
                    "subreddit_name_prefixed": "r/CryptoCurrency",
                    "ups": 2,
                    "media": null,
                    "num_comments": 0,
                    "is_self": false,
                    "visited": false,
                    "mod_note": null,
                    "is_video": false,
                    "distinguished": null
                }
            },

解决方案

This is exactly what json.RawMessage is for (look at the unmarshal example in the docs). Unmarshal the top-level of the JSON Object first, inspect the kind field, then unmarshal the data field:

type Listing struct {                                           
    WhitelistStatus string  `json:"whitelist_status"`           
    Children        []Thing `json:"children"`                   
}                                                               

type T3 struct {                                                
    Domain              string `json:"domain"`                  
    CrosspostParentList []struct {                              
            Domain string `json:"domain"`                       
    } `json:"crosspost_parent_list"`                            
}                                                               

type Thing struct {
    Kind string      `json:"kind"`
    Data interface{} `json:"data"`
}

func (t *Thing) UnmarshalJSON(b []byte) error {
    var step1 struct {
            Kind string          `json:"kind"`
            Data json.RawMessage `json:"data"` 
    }

    if err := json.Unmarshal(b, &step1); err != nil {
            return err
    }

    var step2 interface{}
    switch step1.Kind {
    case "Listing":
            step2 = &Listing{}
    case "t3":
            step2 = &T3{}
    default:
            return errors.New("unknown kind: " + step1.Kind) // or simply ignore
    }

    if err := json.Unmarshal(b, step2); err != nil {
            return err
    }

    t.Kind = step1.Kind
    t.Data = step2

    return nil
}

Try it on the playground: https://play.golang.org/p/giBVT2IWPd-

这篇关于去Unmarshal嵌套未知领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆