第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

fmt.Sprint(e) 在 Error 方法中產(chǎn)生的無限循環(huán)

fmt.Sprint(e) 在 Error 方法中產(chǎn)生的無限循環(huán)

Go
qq_笑_17 2021-09-10 20:57:37
根據(jù)四十四十對這個問題的答復(fù):fmt.Sprint(e)將調(diào)用e.Error()將值轉(zhuǎn)換e為 a string。如果Error()方法調(diào)用fmt.Sprint(e),則程序?qū)⑦f歸,直到內(nèi)存不足。您可以通過將 the 轉(zhuǎn)換為e沒有StringorError方法的值 來中斷遞歸。這對我來說仍然很困惑。為什么 fmt.Sprint(e) 調(diào)用 e.Error() 而不是 String()?我嘗試使用 Stringer 接口,這是我的代碼:package mainimport (  "fmt"  "math")type NegativeSqrt float64func (e NegativeSqrt) Error() string {  fmt.Printf(".")  return fmt.Sprint(e)}func (e NegativeSqrt) String() string {  return fmt.Sprintf("%f", e)}func Sqrt(x float64) (float64, error) {  if x < 0 {    return 0, NegativeSqrt(x)  }  return math.Sqrt(x), nil}func main() {  fmt.Println(Sqrt(2))  fmt.Println(Sqrt(-2))}
查看完整描述

3 回答

?
慕碼人8056858

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 很重要。


查看完整回答
反對 回復(fù) 2021-09-10
?
MMMHUHU

TA貢獻(xiàn)1834條經(jīng)驗(yàn) 獲得超8個贊

因?yàn)轭愋褪莈rror,接口error是


  type error interface{

     Error() string

  }

每個人都error必須有一個Error() string方法,但不一定要有一個String() string方法。這就是為什么首先檢查Error()方法的邏輯。


查看完整回答
反對 回復(fù) 2021-09-10
?
牛魔王的故事

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)


查看完整回答
反對 回復(fù) 2021-09-10
  • 3 回答
  • 0 關(guān)注
  • 348 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號