- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我想执行一些额外的步骤来初始化我的实现 UnmarshalJSON
中的数据结构。在该实现中调用 json.Unmarshal(b, type)
自然会导致堆栈溢出。
JSON 解码器不断尝试查找,如果有自定义的 UnmarshalJSON
实现,然后再次调用 json.Unmarshal
。
还有其他方法吗?只需调用底层默认实现而不会导致这种情况?
最佳答案
避免这种情况/防止这种情况发生的一种简单而常用的方法是使用 type
创建一个新类型关键字,并使用类型 conversion传递此类型的值(该值可能是您的原始值,类型转换是可能的,因为新类型将原始类型作为其基础类型)。
这是有效的,因为 type
关键字创建了一个新类型,而新类型将有零个方法(它不会“继承”底层类型的方法)。
这会产生一些运行时开销吗?编号引用自Spec: Conversions:
Specific rules apply to (non-constant) conversions between numeric types or to and from a string type. These conversions may change the representation of
x
and incur a run-time cost. All other conversions only change the type but not the representation ofx
.
让我们看一个例子。我们有一个带有数字 Age
的 Person
类型,我们要确保 Age
不能为负数(小于 0
)。
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func (p *Person) UnmarshalJSON(data []byte) error {
type person2 Person
if err := json.Unmarshal(data, (*person2)(p)); err != nil {
return err
}
// Post-processing after unmarshaling:
if p.Age < 0 {
p.Age = 0
}
return nil
}
测试它:
var p *Person
fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":10}`), &p))
fmt.Println(p)
fmt.Println(json.Unmarshal([]byte(`{"name":"Bob","age":-1}`), &p))
fmt.Println(p)
输出(在 Go Playground 上尝试):
<nil>
&{Bob 10}
<nil>
&{Bob 0}
当然,同样的技术也适用于自定义编码(marshal)处理 (MarshalJSON()
):
func (p *Person) MarshalJSON() ([]byte, error) {
// Pre-processing before marshaling:
if p.Age < 0 {
p.Age = 0
}
type person2 Person
return json.Marshal((*person2)(p))
}
测试它:
p = &Person{"Bob", 10}
fmt.Println(json.NewEncoder(os.Stdout).Encode(p))
p = &Person{"Bob", -1}
fmt.Println(json.NewEncoder(os.Stdout).Encode(p))
输出(在同一个 Go Playground 示例中):
{"name":"Bob","age":10}
<nil>
{"name":"Bob","age":0}
<nil>
一个非常相似的问题是当您为 fmt
的自定义文本表示定义 String() string
方法时包,并且您想使用您修改的默认字符串表示形式。在这里阅读更多相关信息:The difference between t and *t
关于json - 在 UnmarshalJSON 函数中调用 json.Unmarshal 不会导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43176625/
我正在尝试编写一个简单的自定义编码(marshal)拆收器,但失败了。请注意,我有一个具有三个功能的界面。 Happy 和 Sad 结构都通过嵌入实现所有三个必需功能的 emotion 结构来实现此接
这有效:http://play.golang.org/p/-Kv3xAguDR . 这会导致堆栈溢出:http://play.golang.org/p/1-AsHFj51O . 我不明白为什么。在这种
我在其他语言(如 Java)中创建自己的类型作为枚举值。我为此类型实现了反序列化 UnmarshalJSON 方法,发现 marshal 无法转换为自定义类型 package main import
有人可以帮我看看这里出了什么问题吗?由于某种原因,输出不一样,我不明白为什么。 type rTime time.Time func (rt *rTime) UnmarshalJSON(data []b
所以,我有结构 P。我需要将一些 json 数据解码到 P,但有时它会出现嵌入式结构,Embedded。在任何一种情况下,我都从 API 中解码 json 并需要格式化“Formatted”字段。在嵌
在decode.go ,它提到: // To unmarshal JSON into a value implementing the Unmarshaler interface, // Unmars
我有一个简单的类型,它在 Go 中实现了子类型整数常量到字符串的转换,反之亦然。我希望能够自动将 JSON 中的字符串解码为这种类型的值。我不能,因为 UnmarshalJSON 没有给我返回或修改标
我想 UnmarshalJSON 包含如下接口(interface)的结构: type Filterer interface { Filter(s string) error } type F
当您将 JSON 解码为 []interface{} 时,除了 bool、int 和 string 等标准类型之外,还有什么方法可以自动检测类型吗? 我注意到以下内容,假设我编码 [uuid.UUID
我有一个 struct,它嵌入了一个指向另一个 struct 的嵌入式指针。当我使用默认的 json.Unmarshal 行为时,它工作得很好。但是当我为 embedded struct 的类型实现
我想要使用 base64 在 JSON 中编码和解码的 byte slice RawURLEncoding 而不是 StdEncoding。没有明显的方法可以通过 encoding/json pack
我得到了以下自定义类型: type TimeWithoutZone struct { time.Time } 编码(marshal)处理工作正常: const timeWithoutZoneF
如何在结构中创建方法 UnmarshalJSON,在内部使用 json.Unmarshal 而不会导致堆栈溢出? package xapo type Xapo struct {} func (x Xa
我正在尝试解码具有嵌入式类型的结构。当嵌入类型具有 UnmarshalJSON 方法时,外部类型的解码失败: https://play.golang.org/p/Y_Tt5O8A1Q package
我想执行一些额外的步骤来初始化我的实现 UnmarshalJSON 中的数据结构。在该实现中调用 json.Unmarshal(b, type) 自然会导致堆栈溢出。 JSON 解码器不断尝试查找,如
我的应用程序中有以下结构 // foo.go type FooList struct { Fools []*foo `json:"list"` // maybe Req *h
Go 提供了 encoding/json.Unmarshaler 接口(interface),因此类型可以控制它们从 JSON 解码的方式。在几乎所有情况下,编码后的 JSON 值都直接传递给 Unm
我是一名优秀的程序员,十分优秀!