草庐IT

json - 嵌套结构的解码字段不起作用

coder 2024-07-07 原文

给定以下结构

type Foo struct {
    Thing time.Duration `json:"thing"`
}

type Bar struct {
    Foo
    Entry time.Duration `json:"entry"`
}

我想自定义 time.Duration 格式并从 json 字符串加载 Bar 值,例如:

{
  "thing": "hour",
  "entry": "second"
}

所以我为 FooBar ( https://play.golang.org/p/6v71eG_Xr98 ) 覆盖了 UnmarshalJSON:

package main

import (
    "encoding/json"
    "fmt"
    "time"
)

type Foo struct {
    Thing time.Duration `json:"thing"`
}

type Bar struct {
    Foo
    Entry time.Duration `json:"entry"`
}

func timeConvert(s string) time.Duration {
    if s == "hour" {
        return time.Hour
    }
    if s == "second" {
        return time.Second
    }
    return time.Duration(0)
}

func (t *Foo) UnmarshalJSON(data []byte) error {
    type Alias Foo
    a := struct {
        Thing string `json:"thing"`
        *Alias
    }{Alias: (*Alias)(t)}
    err := json.Unmarshal(data, &a)
    t.Thing = timeConvert(a.Thing)
    fmt.Printf("Foo: %v [%v]\n", *t, err)
    return err
}

func (t *Bar) UnmarshalJSON(data []byte) error {
    type Alias Bar
    a := struct {
        Entry string `json:"entry"`
        *Alias
    }{Alias: (*Alias)(t)}
    err := json.Unmarshal(data, &a)
    t.Entry = timeConvert(a.Entry)
    fmt.Printf("Bar: %v [%v]\n", *t, err)
    return err
}

func main() {
    data := []byte(`{"entry": "second", "thing": "hour"}`)
    json.Unmarshal(data, &Bar{})
}

但它输出意外:

Foo: {1h0m0s} [<nil>]
Bar: {{1h0m0s} 0s} [<nil>]

为什么 Entry 值不正确?

最佳答案

感谢 mkopriva。我发现因为“json.Unmarshal”适用于任何类型,它提示我所有类型都实现了“UnmarshalJSON”功能,但事实并非如此。

在“Bar”上调用“json.Unmarshal”实际上会做以下事情:

  1. Bar 上调用 UnmarshalJSON
  2. 因为 Bar 中的匿名结构没有实现 UnmarshalJSON,所以调用 UnmarshalJSON 嵌入结构 Foo相反。

这就是为什么匿名结构中的“Entry”不会被解码的原因。

mkopriva 建议使用自定义类型来获取自定义解析,但是当您需要将其作为参数传递给 time 包中的函数时,这会很不方便。我想出了另一种方法(只需解码两次,请参阅 https://play.golang.org/p/2ahDX-0hsRt ):

func (t *Bar) UnmarshalJSON(data []byte) error {
    type Alias Bar
    if err := json.Unmarshal(data, (*Alias)(t)); err != nil {
        return err
    }
    var tmp struct {
        Entry string `json:"entry"`
    }
    err := json.Unmarshal(data, &tmp)
    t.Entry = timeConvert(tmp.Entry)
    fmt.Printf("Bar: %v [%v]\n", *t, err)
    return err
}

关于json - 嵌套结构的解码字段不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53228912/

有关json - 嵌套结构的解码字段不起作用的更多相关文章

  1. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  8. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  9. Ruby——嵌套类和子类是一回事吗? - 2

    下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby​​解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc

  10. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

随机推荐