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

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

  • 我正在研究这个简单的问题来练习基本Kotlin,在递归返回行上遇到了堆栈溢出,代码如下: 我对tailrec的理解是,它应该将递归函数转换为迭代函数,而迭代函数不会受到这种崩溃的影响。如果我没有正确实现尾部递归,编译器应该会发出错误。 有人能解释一下为什么这会像标准递归调用一样在大输入上崩溃吗?