首頁 > 後端開發 > Golang > 主體

為什麼在 Go 的'fmt.Stringer”中使用't”與'*t”作為接收器會導致死循環?

Patricia Arquette
發布: 2024-11-22 22:49:12
原創
686 人瀏覽過

Why does using `t` vs `*t` as a receiver in Go's `fmt.Stringer` lead to a dead loop?

理解t 和*t 之間的區別:fmt 套件的案例研究

在Go 中,fmt 套件提供了強大的格式化功能,允許開發人員自訂列印值的方式。然而,t 和 *t 之間的細微差別可能會導致意外行為,即在接收器方法中使用時出現死循環。

考慮以下程式碼片段:

package main

import "fmt"

type TT struct {
    a int
    b float32
    c string
}

func (t *TT) String() string {
    return fmt.Sprintf("%+v", *t)
}

func main() {
    tt := &TT{3, 4, "5"}
    fmt.Printf(tt.String())
}
登入後複製

此程式碼將成功執行,並將「tt」變數的內容列印為「tt={a:3, b:4, c:5 }」。但是,如果我們修改 String 方法如下:

func (t *TT) String() string {
    return fmt.Sprintf("%+v", t)
}
登入後複製

就會導致死迴圈。原因在於 fmt 套件處理實作 String() 方法的值的方式(實作 fmt.Stringer 介面)。

當 'tt' 的值傳遞給 fmt.Println 時,fmt 套件檢查類型 TT 是否實作了 String() 方法。由於我們用指標接收器(*TT)定義了 String() 方法,因此設定為 TT 的方法不包括 String()。因此,fmt 套件不會呼叫 tt.String()。

另一方面,在修改後的程式碼片段中,我們定義了接收器類型為 *TT 的 String() 方法。在這種情況下,為TT設定的方法包括String()。但是,由於我們傳遞的是 *TT 類型的 tt,因此呼叫 tt.String() 本質上是遞歸呼叫 String() 方法,從而導致無限迴圈。

為了防止此問題,建議對 String() 方法使用不同的接收器類型。一種方法是使用 type 關鍵字建立新類型並對傳遞的值執行類型轉換。這會建立一個沒有方法的新類型,避免無限循環。

例如:

func (t TT) String() string {
    type TT2 TT
    return fmt.Sprintf("%+v", TT2(t))
}
登入後複製

在這種情況下,將 t 轉換為 TT2 有效地確保 String() 方法不會被遞歸調用,因為 TT2 沒有 String() 方法。

理解 t 和 *t 在上下文中的區別fmt 套件對於避免意外行為並確保高效的程式碼執行至關重要。

以上是為什麼在 Go 的'fmt.Stringer”中使用't”與'*t”作為接收器會導致死循環?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板