Go 为什么在Error()方法中调用fmt.Sprint(e)会导致无限循环?
我正在复习教程 我想核对一下这个问题的答案: 注意:调用Go 为什么在Error()方法中调用fmt.Sprint(e)会导致无限循环?,go,Go,我正在复习教程 我想核对一下这个问题的答案: 注意:调用Error方法中的fmt.Sprint(e),将发送 将程序转换为无限循环。您可以通过转换 efirst:fmt.Sprint(float64(e))。为什么? 我认为这是因为当调用Sprint函数时,由于错误为非nil,因此将再次调用error函数(),以此类推,从而导致无限循环 fmt.Sprint(e)将调用e.Error()将值e转换为字符串。如果Error()方法调用fmt.Sprint(e),则程序将递归,直到内存不足 您可以
Error
方法中的fmt.Sprint(e)
,将发送
将程序转换为无限循环。您可以通过转换
e
first:fmt.Sprint(float64(e))
。为什么?
我认为这是因为当调用
Sprint
函数时,由于错误为非nil,因此将再次调用error函数()
,以此类推,从而导致无限循环 fmt.Sprint(e)
将调用e.Error()
将值e
转换为字符串。如果Error()
方法调用fmt.Sprint(e)
,则程序将递归,直到内存不足
您可以通过将e
转换为不带字符串或错误方法的值来中断递归。fmt。Sprint(e)将从“fmt/print.go”调用以下代码段
当错误案例首先出现时,将执行v.error()。无止境的循环 将e转换为一种可能具有字符串/错误方法且不会无限递归的类型难道还不够吗?是的,fmt.Sprintf(“不能Sqrt负数:%f”,e)
works但它为什么尝试调用e.Error()
进行转换?如果我试图让它实现Stringer接口,它不会尝试调用它。是什么让它找到了Error()
方法?@hytromo In,Sprint
最终导致了handleMethods
,动词为v
。检查参数是否满足Stringer之前的错误类型,从而调用error()
方法,而不是String()
。谢谢,我在这里了解到了这一点:
switch verb {
case 'v', 's', 'x', 'X', 'q':
// Is it an error or Stringer?
// The duplication in the bodies is necessary:
// setting handled and deferring catchPanic
// must happen before calling the method.
switch v := p.arg.(type) {
case error:
handled = true
defer p.catchPanic(p.arg, verb, "Error")
p.fmtString(v.Error(), verb)
return
case Stringer:
handled = true
defer p.catchPanic(p.arg, verb, "String")
p.fmtString(v.String(), verb)
return
}
}