首页  >  文章  >  后端开发  >  为什么 Go 的'fmt.Println”使用嵌入类型和多个'String()”方法会产生意外的输出?

为什么 Go 的'fmt.Println”使用嵌入类型和多个'String()”方法会产生意外的输出?

DDD
DDD原创
2024-11-21 20:23:18992浏览

Why Does Go's `fmt.Println` Produce Unexpected Output with Embedded Types and Multiple `String()` Methods?

Go 嵌入类型中意外的 String() 方法行为

在 Go 中使用嵌入类型时,嵌入类型的字段和方法是拥抱型有效地继承了这一点。这可能会导致意外行为,尤其是在处理自定义 String() 方法时。

考虑以下示例:

在此代码中,Engineer 类型嵌入了 Person 和 TaxPayer 类型,它们定义自己的 String() 方法来格式化相应的数据。但是,如果我们实例化一个 Engineer 对象并调用 fmt.Println(engineer),则输出并不符合预期:

此输出表明正在调用 Engineer.String() 方法,但TaxPayer.String() 方法也对结果有贡献。这是因为 String() 方法在嵌入时会提升为 Engineer 类型,并且 Person.String() 和 TaxPayer.String() 方法都可以调用。

为了澄清这一点,请考虑以下内容场景:

在这种情况下,编译器会引发错误,因为工程师有多个提升的 String() 方法,导致选择器不明确。然而,fmt.Println(engineer) 会成功,因为编译器会根据其字段自动选择 Engineer 的默认格式。

造成这种明显差异的原因是 fmt.Println() 函数本质上委托了字符串转换到 fmt 包。当它遇到实现 fmt.Stringer 接口(定义 String() 方法)的值时,它会调用该方法来获取字符串表示形式。

在我们的示例中,因为 Person.String() 和TaxPayer.String() 存在,两者均未晋升为工程师,并使用默认格式。然而,在 fmt.Println(engineer.String()) 的情况下,编译器会遇到不明确的选择器并引发错误。

总之,当多个嵌入类型定义了此类方法。了解嵌入和方法提升的机制非常重要,以避免潜在的混乱并确保所需的输出。

以上是为什么 Go 的'fmt.Println”使用嵌入类型和多个'String()”方法会产生意外的输出?的详细内容。更多信息请关注PHP中文网其他相关文章!

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