首页  >  文章  >  后端开发  >  为什么在'String()”方法中使用指针接收器可以防止 Go 字符串格式化中的死循环?

为什么在'String()”方法中使用指针接收器可以防止 Go 字符串格式化中的死循环?

Linda Hamilton
Linda Hamilton原创
2024-11-23 04:06:20424浏览

Why Does Using a Pointer Receiver for `String()` Method Prevent a Dead Loop in Go String Formatting?

理解 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn