英文:
Why would a call to fmt.Sprint(e) inside the Error() method result in an infinite loop?
问题
我正在进行《Go之旅》教程。
我想要检查这个问题的答案:
注意: 在
Error
方法中调用fmt.Sprint(e)
会导致程序进入无限循环。你可以通过先将e
转换为fmt.Sprint(float64(e))
来避免这种情况。为什么?
我认为这是因为当调用Sprint
函数时,由于错误是非空的,Error
方法将再次被调用,如此循环下去,导致无限循环。
英文:
I am going through "A Tour of Go" tutorial.
I would like to check the answer to this question:
> Note: a call to fmt.Sprint(e)
inside the Error
method will send
> the program into an infinite loop. You can avoid this by converting
> e
first: fmt.Sprint(float64(e))
. Why?
<br>
I believe this is because when the Sprint
function is called, since the error is non-nil, the Error function()
will again be called, and so forth, resulting in an infinite loop.
答案1
得分: 94
fmt.Sprint(e)
将调用e.Error()
将值e
转换为string
。如果Error()
方法调用fmt.Sprint(e)
,那么程序将递归调用直到内存耗尽。
你可以通过将e
转换为一个没有String
或Error
方法的值来打破递归。
英文:
fmt.Sprint(e)
will call e.Error()
to convert the value e
to a string
. If the Error()
method calls fmt.Sprint(e)
, then the program recurses until out of memory.
You can break the recursion by converting the e
to a value without a String
or Error
method.
答案2
得分: 15
fmt.Sprint(e)将调用来自"fmt/print.go"的以下代码片段:
switch verb {
case 'v', 's', 'x', 'X', 'q':
// 它是一个错误还是Stringer?
// 在这些代码块中的重复是必要的:
// 在调用方法之前,设置handled和延迟catchPanic
// 必须发生。
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
}
}
由于错误情况首先出现,v.Error()将被执行。这里会出现无限循环!
英文:
fmt.Sprint(e) will invoke the following piece of codes from "fmt/print.go"
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
}
}
As error case appears first, v.Error() will be executed. Endless loop here!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论