字串方法中的指標接收器與值接收器
Go 中,String() 方法用於控制自訂的字符串表示類型。定義 String() 方法時,理解指標接收器和值接收器之間的差異至關重要。
考慮以下程式碼:
type TT struct { a int b float32 c string } func (t *TT) String() string { return fmt.Sprintf("%+v", *t) }
在此程式碼中, String( ) 方法有一個指標接收器,這表示它對指向 TT 值的指標進行操作。呼叫 tt.String() 有效地呼叫 (*tt).String()。
現在,請考慮將 String() 方法變更為以下內容:
func (t *TT) String() string { return fmt.Sprintf("%+v", t) }
此變更會刪除指標接收者,使 String() 方法對 TT 類型的值進行操作。
為什麼會導致死Loop?
fmt 套件檢查正在列印的值是否實作了 Stringer 介面(或具有 String() 方法)。如果是,它將調用該方法來獲取字串表示形式。然而,在這種情況下,我們有一個 String() 方法的指標接收器。
當我們呼叫 tt.String() 時,fmt 套件傳遞一個 *TT 類型的值。但是,String() 方法需要 TT 類型的值。這種不匹配會導致 fmt 套件再次調用 String() 方法,而 String() 方法又會再次調用,依此類推,導致無限迴圈。
預防/保護
為了防止這種死循環,請確保 String() 方法的接收者類型與傳遞給 fmt 套件的值的類型相符。如果你因為某些原因需要使用相同的接收器類型,你可以使用type 關鍵字建立一個新類型,並在呼叫fmt.Sprintf 之前將值轉換為新類型:
func (t TT) String() string { type TT2 TT return fmt.Sprintf("%+v", TT2(t)) }
透過建立一個新的類型,我們從底層類型中刪除所有方法,有效地打破循環並允許我們安全地呼叫fmt.Sprintf。
以上是為什麼字串方法中的指標接收器會導致Go中的死循環?的詳細內容。更多資訊請關注PHP中文網其他相關文章!