json - 为什么编码(marshal)无法使用嵌套结构?

标签 json go unmarshalling

我正在尝试使用Reddit的API检索信息。 Here是有关其json响应的一些文档,但是,我只是通过在浏览器中查看链接并漂亮地打印响应here来获得大部分信息。
当注释掉“答复”字段时,以下代码将按预期方式运行,但当未注释时,它将失败。
[edit] getData()是我编写的一个函数,它使用Go的http客户端获取以字节为单位的站点响应。

type redditThing struct {
    Data struct {
        Children []struct {
            Data struct {
                Permalink string
                Subreddit string
                Title     string
                Body      string
                Replies   redditThing
            }
        }
    }
}

func visitLink(link string) {
    println("visiting:", link)

    var comments []redditThing
    if err := json.Unmarshal(getData(link+".json?raw_json=1"), &comments); err != nil {
        logError.Println(err)
        return
    }
}
这将引发以下错误
json: cannot unmarshal string into Go struct field .Data.Children.Data.Replies.Data.Children.Data.Replies.Data.Children.Data.Replies of type main.redditThing
任何帮助将不胜感激。谢谢大家!
[edit] here指向某些数据的链接,导致程序失败

最佳答案

replies字段可以是空字符串或redditThing。通过添加Unmarshal函数来处理空字符串进行修复:

func (rt *redditThing) UnmarshalJSON(data []byte) error {
    // Do nothing if data is the empty string.
    if bytes.Equal(data, []byte(`""`)) {
        return nil
    }

    // Prevent recursion by declaring type x with 
    // same underlying type as redditThing, but
    // with no methods.
    type x redditThing

    return json.Unmarshal(data, (*x)(rt))
}
x类型用于防止不确定的递归。如果该方法的最后一行是json.Unmarshal(data, rt),则json.Unmarshal函数将调用redditThing.UnmarshalJSON方法,该方法又调用json.Unmarshal函数,依此类推。繁荣!
语句type x redditThing声明了一个名为x的新类型,其基础类型与redditThing相同。基础类型是匿名结构类型。基础类型没有方法,并且至关重要的是,基础类型没有UnmarshalJSON方法。这样可以防止递归。

关于json - 为什么编码(marshal)无法使用嵌套结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62506468/

相关文章:

go - 如何为 Go 中的行插入重用单个 Postgres DB 连接?

java - 如何将多个元素映射到 JAXB 中的单个类

java - JAXB 逐个元素解码列表

java - 使用架构问题的 XSD 验证

javascript - 使用 PHP 和 JSON 平面文件的最佳实践/方法

javascript - 我们如何从 javascript 对象中获取字符串值?

javascript - 解析 json 对象时 eval() 不是必需的吗?

java - 如何在两个 Activity 之间显示不同的 json 数据?

amazon-web-services - 多年来无法预签名 URL?

go - 如何将验证器标记添加到嵌套字段