当前位置: 首页 > 面试题库 >

UnmarshalJSON导致堆栈溢出

秦宏盛
2023-03-14
问题内容

这有效:http :
//play.golang.org/p/-Kv3xAguDR。

这导致堆栈溢出:http :
//play.golang.org/p/1-AsHFj51O。

我不明白为什么。JSONUnmarshaler在这种情况下,使用接口的正确方法是什么?

package main

import (
    //"bytes"
    "encoding/json"
    "fmt"
    "strings"
)

type T interface {
    Printer()
}

type A struct{ JA string }

func (t A) Printer() { fmt.Print("A") }

/*
func (t *A) UnmarshalJSON(data []byte) error {
    i := A{}
    dec := json.NewDecoder(bytes.NewReader(data))
    if err := dec.Decode(&i); err != nil {
        return err
    }
    i.Printer()
    *t = i
    return nil
}
*/

var vI []T

func main() {
    vI = []T{&A{}}
    get()
}

func get() {
    dec := json.NewDecoder(strings.NewReader("[{\"JA\":\"OK\"}]"))
    if err := dec.Decode(&vI); err != nil {
        fmt.Print(err)
    }
    for _, v := range vI {
        v.Printer()
    }
}

问题答案:

这个

dec.Decode(&i)

将呼叫您的UnmarshalJSON,依次呼叫Decode,等等。如果您需要解组JSON然后对其进行处理,那么一种巧妙的技术是声明一个本地类型,将数据解组到其中,然后转换回所需的类型:

// Type a has no UnmarshalJSON.
type a A
i := a{}
dec := json.NewDecoder(bytes.NewReader(data))
if err := dec.Decode(&i); err != nil {
    return err
}
// Convert back to A.
tt := A(i)
tt.Printer()
*t = tt
// ...

游乐场:http :
//play.golang.org/p/HWamV3MbvW。

该类型a没有方法(因此没有堆栈溢出),但是可以转换为A



 类似资料:
  • 我正在使用一个正则表达式从任意长的输入字符串中提取键值对,并且遇到了这样的情况:对于具有重复模式的长字符串,它会导致堆栈溢出。 KV解析代码如下所示: 一些虚构的输出示例: 我显式地将generic放在上面,而不是在解析之前检查最大字符串长度的hacks(例如)。 我能想出的最粗俗的解决方法,一个真正的反模式,是 有趣的是,它在我试过的几次运行中都起作用了,但它不是一个值得推荐的有品位的东西。:-

  • 问题内容: TL; DR: 将任何非内置函数添加到Array.prototype AND Function.prototype将导致IE8本机JSON解析器在解析包含数组的任何JSON时发生堆栈溢出,但仅当您还传递了reviver函数时放入JSON.parse()。 最初这是一个问题,但我回答了我自己的原始问题,所以现在我要问:有人能想到此IE8错误的解决方法,该方法不涉及消除所有修改Array.

  • 我有一个名为User的实体,它有一组角色。我还有一个角色实体,它有一组用户。(这只是出于学习目的的实践应用。) 问题是——我有一个UserController(REST API)来发送用户列表——这会导致StackOverFlow错误。用户试图加载角色,而角色又试图加载用户等。 我的问题是——如何避免这种情况?我也看到许多类似的设计。例如:https://viralpatel.net/blogs/

  • 我找不到堆栈溢出的来源,但似乎是外部的循环造成的。 提前道谢!

  • 问题内容: 我到处都是,找不到可靠的答案。根据文档,在以下情况下,Java引发java.lang.StackOverflowError错误: 由于应用程序递归过深而在堆栈溢出时抛出。 但这提出了两个问题: 不仅通过递归,还有其他方法可以使堆栈溢出吗? 是在JVM实际溢出堆栈之前还是之后发生StackOverflowError? 详细阐述第二个问题: 当Java引发StackOverflowErro

  • 问题内容: 我想执行一些其他步骤来初始化实现中的数据结构。在该实现内调用自然会导致堆栈溢出。 JSON解码器会不断尝试查找,如果有自定义实现,然后再次调用。 还有另一种方法吗?只是调用基本的默认实现而不会导致此问题? 问题答案: 避免这种情况/避免这种情况发生的一种简单且常见的方法是使用关键字创建一个新类型,并使用类型转换来传递该类型的值(该值可能是您的原始值,因为新的类型具有原始类型作为其基础类