fmt.Println 和 String() 方法
為什麼 fmt.Println 在呼叫時不利用成員的 String() 方法一個結構?讓我們檢查一下底層機制。
考慮以下程式碼:
import "fmt" type Bar struct{} func (b Bar) String() string { return "bar" } type Foo struct { B []*Bar BB *Bar } func main() { f := Foo{B: []*Bar{&Bar{}}, BB: &Bar{}} fmt.Println(f, f.B, f.BB) }
此程式碼產生預期的輸出:
{[(addr: 0x8201dde620)] (addr: 0x8201dde620)} [bar] bar
但是,您可能想知道為什麼輸出不是如下所示:
{[bar] bar} [bar] bar
它將顯示成員的String() 表示形式而不是記憶體位址。
原因在於 Bar 型別及其未匯出的性質String() 方法。在 Go 中,未匯出的成員和方法只能在定義它們的套件內存取。由於 fmt.Println 不是相同套件的一部分,因此它無法存取這些未導出的元素。因此,它採用列印非內建類型的記憶體位址的預設行為。
要解決此問題,您需要匯出 Bar 類型及其 String() 方法。此外,還必須匯出 Foo 結構中的欄位以進行正確的 JSON 編碼和解碼。
這是程式碼的修改版本,示範了正確的方法:
import "fmt" type Bar struct{} func (b Bar) String() string { return "bar" } type Foo struct { B []*Bar BB *Bar } func main() { f := Foo{B: []*Bar{&Bar{}}, BB: &Bar{}} fmt.Println(f) }
進行了這些變更實作後,輸出現在將是:
{[bar] bar} [bar] bar
此範例強調了使用匯出類型和方法與fmt.Println 等格式化程式進行適當整合的重要性。
以上是為什麼「fmt.Println」不使用結構體的「String()」方法,除非匯出結構體和方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!