理解 Go 字符串格式中“t”和“*t”的区别
Go 程序中,变量名可以加前缀用星号 (*) 表示指针类型。这种区别在使用 fmt 包进行字符串格式化的情况下至关重要。
问题:
考虑以下代码:
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()) }
为什么当 String 有一个指针接收器(func (t *TT) String() string)时,代码是否工作,但当接收器是一个指针时,代码会导致死循环非指针类型(func (t TT) String() string)?
答案:
fmt 包检查 String() 方法是否存在它接收的操作数。当String的接收者是指针类型时,基类型的方法集不包含String(),所以fmt包不会调用它。
相反,当接收者是非指针时类型,String()包含在基类型的方法集中。这意味着 fmt 包调用 String(),在本例中,与被调用的方法相同,从而导致无限循环。
预防:
避免这种无限循环,请考虑使用 type 关键字创建一个新类型,并对正在格式化的值应用类型转换:
func (t TT) String() string { type TT2 TT return fmt.Sprintf("%+v", TT2(t)) }
这种方法可以防止通过在 type 关键字创建的新类型中隔离 String() 方法来实现间接递归。
以上是为什么在'String()”方法中使用指针接收器可以防止 Go 字符串格式化中的死循环?的详细内容。更多信息请关注PHP中文网其他相关文章!