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
        }
    }