好的,所以我有这段代码func registerDomain(domainName string, n int) bool { //building the request here resp, errr := client.Do(r) if errr != nil { if n == 1 { return false } registerDomain(domainName, n-1) } bodyBytes, err2 := ioutil.ReadAll(resp.Body) if err2 == nil { resp.Body.Close() //handle bodyBytes //if the response is how it should be return true, if it's not call the function again with n-1 } else { //if there is an error reading the response resp.Body.Close() if n == 1 { return false } registerDomain(domainName, n-1) } return false //it should never reach this line}解释:我使用参数 n(假设为 5)调用该函数,该参数表示如果出现问题,该函数将重试的次数。每次出现问题时,我都会使用 n-1 进行递归调用,因此当它达到 n=1 时,它放弃并返回 false。这段代码在实践中运行良好,它完成了它应该做的事情,有时当响应不正确时,它会递归调用自己,并在第二次(或第三次、第四次......)时间工作。当问题在 n=1 之前没有解决时,它返回 false。问题:这是一个应该运行大约 17 小时的大代码的一部分,当它试图从这一行读取正文时,它有时会出现恐慌:bodyBytes, err2 := ioutil.ReadAll(resp.Body)它说恐慌:运行时错误:无效的内存地址或零指针取消引用。现在我知道这可能意味着它试图从不存在的 resp.Body 中读取,但是Go 文档明确指出,当 err 为零时, resp 总是包含一个非零的 resp.Body。所以,在我看来,这可能与递归调用有关。该只说对我来说很有意义的事情是这样的情景:让说,errr不为零(这意味着resp.Body不存在),如此这般的,如果errr内部=零,因为N =! 1,它将以 n=4 再次调用自己。比方说,这个时候一切都是理所应当的而第二个函数返回true的第一个BUT的第一个与执行,并继续尝试从一个不存在的resp.Body阅读。这会引起恐慌,我们在这里......所以,我需要的是一个确切知道递归函数如何工作的人,如果不是这样,我能否在阅读表单之前以某种方式检查 resp.Body 的存在,或者有帮助的东西。不管怎么说,多谢拉!:)更新:你没事,我的代码不再恐慌,我也一样。非常感谢!(我不确定这是不是更新的地方)
3 回答
噜噜哒
TA贡献1784条经验 获得超7个赞
改变
registerDomain(domainName, n-1)
到
return registerDomain(domainName, n-1)
这样外部函数将不会继续执行并且不会从 nil 主体中读取。
- 3 回答
- 0 关注
- 218 浏览
添加回答
举报
0/150
提交
取消