gpt4 book ai didi

go - 为什么我的 Stringer 接口(interface)方法没有被调用?使用 fmt.Println 时

转载 作者:IT老高 更新时间:2023-10-28 12:58:46 25 4
gpt4 key购买 nike

假设我有以下代码:

package main

import "fmt"

type Car struct{
year int
make string
}

func (c *Car)String() string{
return fmt.Sprintf("{make:%s, year:%d}", c.make, c.year)
}

func main() {
myCar := Car{year:1996, make:"Toyota"}
fmt.Println(myCar)
}

当我调用 fmt.Println(myCar) 并且有问题的对象是一个指针时,我的 String() 方法会被正确调用。但是,如果对象是一个值,则我的输出将使用 Go 内置的默认格式进行格式化,并且不会调用用于格式化所述对象的代码。

有趣的是,无论哪种情况,如果我手动调用 myCar.String(),无论我的对象是指针还是值,它都能正常工作。

在与 Println 一起使用时,无论对象是基于值还是基于指针,我如何才能按照我想要的方式格式化对象?

我不想为 String 使用 value 方法,因为这意味着每次调用它时都会复制对象,这不合理。而且我不想总是手动调用 .String() ,因为我试图让鸭子打字系统完成它的工作。

最佳答案

调用 fmt.Println 时,myCar 被隐式转换为 interface{} 类型的值,从函数签名中可以看出. fmt 包中的代码然后执行 type switch弄清楚如何打印这个值,看起来像这样:

switch v := v.(type) {
case string:
os.Stdout.WriteString(v)
case fmt.Stringer:
os.Stdout.WriteString(v.String())
// ...
}

但是,fmt.Stringer 案例失败,因为 Car 没有实现 String(因为它在 *Car 上定义)。手动调用 String 是因为编译器看到 String 需要 *Car 并因此自动转换 myCar.String()(&myCar).String()。对于有关接口(interface)的任何事情,您都必须手动完成。因此,您要么必须在 Car 上实现 String,要么总是将指针传递给 fmt.Println:

fmt.Println(&myCar)

关于go - 为什么我的 Stringer 接口(interface)方法没有被调用?使用 fmt.Println 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16976523/

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