gpt4 book ai didi

string - t和*t的区别

转载 作者:IT王子 更新时间:2023-10-29 01:52:23 27 4
gpt4 key购买 nike

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 方法,它将导致死循环。区别在于 *t 被替换为 t。为什么?

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

最佳答案

因为 fmt package 检查打印的值是否有 String() string 方法(或者换句话说:如果它实现了 fmt.Stringer 接口(interface)),如果有,它将被调用以获取 >string 值的表示。

这在 fmt 包文档中有记录:

[...] If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).

这里:

return fmt.Sprintf("%+v", *t)

您正在将 TT 类型的值 *t 传递给 fmt 包。如果 TT.String() 方法有一个指针接收器,那么 method set TT 类型的不包含 String() 方法,因此fmt 包不会调用它(只有 *TT 的方法集包含它。

如果将接收者改为非指针类型,那么TT类型的方法集将包含String()方法,所以 fmt 包会调用它,但这是我们目前使用的方法,所以这是一个无休止的“间接递归”。

预防/保护

如果出于某种原因您确实需要使用与传递给 fmt 包的值类型相同的接收器类型,那么避免这种情况/防止这种情况发生的一种简单而常用的方法是使用 type 创建一个新类型关键字,并使用类型 conversion关于传递的值:

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

Go Playground 上试试这个.

但是为什么这行得通呢?因为 type 关键字创建了一个新类型,并且新类型将具有 方法(它不会“继承”基础类型的方法)。

这会产生一些运行时开销吗?编号引用自Spec: Type declarations :

Specific rules apply to (non-constant) conversions between numeric types or to and from a string type. These conversions may change the representation of x and incur a run-time cost. All other conversions only change the type but not the representation of x.

在这里阅读更多相关信息:Does convertion between alias types in Go create copies?

关于string - t和*t的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43065856/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com