首页 > 后端开发 > Golang > 为什么 Go 在编译时不检测嵌入式结构的 String() 方法调用中的歧义?

为什么 Go 在编译时不检测嵌入式结构的 String() 方法调用中的歧义?

Linda Hamilton
发布: 2024-11-26 03:05:10
原创
208 人浏览过

Why Doesn't Go Detect Ambiguity in String() Method Invocation for Embedded Structs at Compile Time?

Go 中嵌入结构的奇怪方法调用:理解 String()

在 Go 中,嵌入结构继承其嵌入类型的方法。但是,当多个嵌入类型定义具有相同名称的方法时,就会出现歧义。让我们特别关注 String() 方法来探索这种行为。

在提供的示例代码中:

type Engineer struct {
    Person
    TaxPayer
    Specialization string
}

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("name: %s, age: %d", p.Name, p.Age)
}

type TaxPayer struct {
    TaxBracket int
}

func (t TaxPayer) String() string {
    return fmt.Sprintf("%d", t.TaxBracket)
}
登录后复制

当使用 fmt.Println(engineer) 打印 Engineer 结构体时,输出根据嵌入类型中是否存在 String() 方法而变化。

与Person.String():

  • fmt 调用 Person.String(),因为它在 Engineer 类型中具有最浅的深度。
  • 输出为:“{name: John Doe,年龄:35 3 建筑}"

无Person.String():

  • fmt 调用 TaxPayer.String(),因为它是唯一升级的 String() 方法。
  • 输出为:“3”

没有两个 String()方法:

  • 不能从嵌入类型提升 String() 方法。
  • fmt 打印默认字段值:“{{John Doe 35} {3}构造}"

这些场景突出了 Go 中提升方法的深度规则和歧义解决。然而,问题出现了,为什么当存在多个深度为零的 String() 方法时,在编译时没有检测到歧义性。

不明确的选择器检查:

通常,当尝试使用不明确的选择器调用方法(例如 Engineer.Foo())时,会发生编译时错误。但是,使用名为 String() 的方法不会发生这种情况。

原因:

在未显式调用其 String() 方法的情况下打印值时, fmt.Println函数检查该值是否实现 fmt.Stringer。然后它调用已实现的 String() 方法。由于所有 Go 类型默认都隐式实现 Stringer (https://golang.org/doc/go1.19#fmt),因此任何类型总有一个提升的 String() 方法。

结论:

嵌入结构的方法调用的歧义性是由于深度规则和用于打印的 String() 方法的特殊处理而产生的价值观。通过了解这些规则以及方法提升中的细微差别,开发人员可以避免意外行为并保持 Go 程序中代码的清晰度。

以上是为什么 Go 在编译时不检测嵌入式结构的 String() 方法调用中的歧义?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板