3 回答

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個贊
好像直接說明就是 fmt 包的來源:
// Is it an error or Stringer?
// The duplication in the bodies is necessary:
// setting handled and deferring catchPanic
// must happen before calling the method.
然后調(diào)用Error()或String()。
這意味著第一個error.Error()被調(diào)用以生成字符串,然后再次處理并打印為字符串。
這里是否error有方法String無關(guān)緊要。問題是為什么NegativeSqrt用一種方法而不是另一種方法打印。鍵入NegativeSqrt同時實(shí)現(xiàn)了fmt.Stringer與error接口,所以它是由執(zhí)行fmt封裝的接口應(yīng)該被用來獲取string來自NegativeSqrt(因?yàn)閒mt.Sprint通過采用其參數(shù)interface{})。
為了說明這一點(diǎn),請考慮以下示例:
package main
import (
"fmt"
)
type NegativeSqrt float64
func (e NegativeSqrt) Error() string {
return ""
}
func (e NegativeSqrt) String() string {
return ""
}
func check(val interface{}) {
switch val.(type) {
case fmt.Stringer:
fmt.Println("It's stringer")
case error:
fmt.Println("It's error")
}
}
func check2(val interface{}) {
switch val.(type) {
case error:
fmt.Println("It's error")
case fmt.Stringer:
fmt.Println("It's stringer")
}
}
func main() {
var v NegativeSqrt
check(v)
check2(v)
}
執(zhí)行這個給出:
% go run a.go
It's stringer
It's error
這是因?yàn)樵?Go 中類型 switch 的行為就像普通 switch 一樣,所以case 的 order 很重要。

TA貢獻(xiàn)1834條經(jīng)驗(yàn) 獲得超8個贊
因?yàn)轭愋褪莈rror,接口error是
type error interface{
Error() string
}
每個人都error必須有一個Error() string方法,但不一定要有一個String() string方法。這就是為什么首先檢查Error()方法的邏輯。

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個贊
讓我擴(kuò)展 tumdum 的發(fā)現(xiàn),以便更清楚。
我將從一個呼叫跳轉(zhuǎn)到另一個呼叫以展示我們?nèi)绾芜M(jìn)入循環(huán)。
我們從練習(xí)開始
func (e NegativeSqrt) Error() string { fmt.Printf(".") return fmt.Sprint(e)}
這將我們帶到fmt/print.go的第 237 行:
func Sprint(a ...interface{}) string
在函數(shù)內(nèi)部,我們的下一個跳轉(zhuǎn)在第 239 行:
p.doPrint(a, false, false)
我們到達(dá)第 1261 行:
func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
在該函數(shù)中,我們將使用我們的error
參數(shù)跳轉(zhuǎn)到第 1273 行:
prevString = p.printArg(arg, 'v', 0)
我們在第 738 行到達(dá)了一個巨大的核心怪物函數(shù):
func (p *pp) printArg(arg interface{}, verb rune, depth int) (wasString bool) {
在里面,你可以看到一個大switch case
開關(guān)。error
進(jìn)入該default
部分,因?yàn)樗徽J(rèn)為是一個非平凡的類型。
這將我們帶到第 806 行并調(diào)用handleMethods()
:
if handled := p.handleMethods(verb, depth); handled {
我們到達(dá)第 688 行:
func (p *pp) handleMethods(verb rune, depth int) (handled bool) {
在該函數(shù)內(nèi)部,在第 724 行,調(diào)用Error()
發(fā)生,從而完成循環(huán):
p.printArg(v.Error(), verb, depth)
- 3 回答
- 0 關(guān)注
- 348 瀏覽
添加回答
舉報