Golang中组合(composition)的性能表现为何如此?
Golang中组合(composition)的性能表现为何如此?
package main
import (
"fmt"
)
type aki float64
func(a aki) String() string {
return fmt.Sprintf("%.2f C", a)
}
type di struct {
aki
name string
}
func main() {
ak := aki(5)
fmt.Println(ak)
d := di{7, "daria"}
fmt.Println(d)
}
为什么当我执行 fmt.Println(d) 时没有打印 name 字段,我必须显式地写 d.name 才能打印出 “daria”
更多关于Golang中组合(composition)的性能表现为何如此?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
func (d di) String() string {
return fmt.Sprintf("%s %s", d.aki, d.name)
}
更多关于Golang中组合(composition)的性能表现为何如此?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
如果某些方法或字段在 di 上不可用,它们将被转发到 aki,由于您没有为 di 实现 String() 方法,因此会使用 aki 的方法。
在Go语言中,当使用组合(composition)时,嵌入类型的方法会被提升到外层类型中。在你的代码中,di 结构体嵌入了 aki 类型,因此 aki 的 String() 方法被提升为 di 的方法。
当调用 fmt.Println(d) 时,fmt 包会检查 di 是否实现了 Stringer 接口(即是否有 String() string 方法)。由于 aki 的 String() 方法被提升,di 也满足 Stringer 接口,所以会调用这个 String() 方法而不是使用默认的格式化输出。
aki 的 String() 方法只返回 aki 字段的格式化字符串,没有包含 name 字段的信息。这就是为什么 fmt.Println(d) 只显示温度值而没有显示名称的原因。
如果你希望打印完整的 di 结构体信息,有几种解决方案:
- 为
di实现自定义的String()方法:
func (d di) String() string {
return fmt.Sprintf("{%v %s}", d.aki, d.name)
}
- 使用默认的结构体格式化(不实现
String()方法):
// 移除 aki 的 String() 方法,或者使用 fmt.Printf 的 %+v 格式
fmt.Printf("%+v\n", d)
- 显式访问字段:
fmt.Println(d.aki, d.name)
修改后的完整示例:
package main
import (
"fmt"
)
type aki float64
func (a aki) String() string {
return fmt.Sprintf("%.2f C", a)
}
type di struct {
aki
name string
}
// 为 di 实现自定义 String() 方法
func (d di) String() string {
return fmt.Sprintf("Temperature: %v, Name: %s", d.aki, d.name)
}
func main() {
ak := aki(5)
fmt.Println(ak) // 输出: 5.00 C
d := di{7, "daria"}
fmt.Println(d) // 输出: Temperature: 7.00 C, Name: daria
}
这是Go语言组合特性的正常行为,方法提升机制使得嵌入类型的方法对外层类型可用,但有时需要根据具体需求实现适当的方法重写。

