Golang中嵌入式结构体字段的初始化名称是什么

Golang中嵌入式结构体字段的初始化名称是什么 给定

type point struct {
	position float64
}
type shapebase struct {
	point
}
type circle struct {
	shapebase
	radius float64
}

如何使用命名字段初始化一个圆形结构体?我尝试了所有我能想到的变体,例如:

p := &circle{radius: 5.0, position: shapebase{point{3.0}}}

但所有尝试都收到类似以下的错误:

无法在类型为 circle 的结构体字面量中使用被提升的字段 shapebase.point.position


更多关于Golang中嵌入式结构体字段的初始化名称是什么的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

p := &Circle{shapebase: shapebase{point{3.0}}, radius: 5.0}

我建议使用一个构造函数:

func NewCircle(pos point, rad float64) *Circle {
    return &Circle{
        shapebase: shapebase{
            point: point,
        },
        radius: rad,
    }
}

更多关于Golang中嵌入式结构体字段的初始化名称是什么的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


谢谢。好的。我想我具体问题的答案是,你需要嵌入结构体的名称出现两次:shapebase: shapebase{...}

我称之为工厂模式而非构造函数,不过无所谓。

我想 Go 语言没有真正的构造函数。我不太确定我是否“理解”这一点。人们应该如何设计一个复杂的结构体,并确保每个实例在使用前都具有“内部完整性”或内部一致性,或者所有必需的字段都已填充?析构函数也一样:自动垃圾收集是否完全消除了结构体需要一种严格的方法来在自身之后进行清理的必要性?

显然,Go 语言是由比我知识渊博得多的人设计的,但我不确定我是否喜欢数据和方法的分离。在我看来,这在面向对象编程中是一种倒退。封装不重要吗?还是说 Go 语言打算在包级别而非结构体级别来处理这个问题?

在Go语言中,当使用嵌入式结构体时,被提升的字段在初始化时需要使用完整的字段路径。对于你的结构体定义,正确的初始化方式如下:

package main

import "fmt"

type point struct {
	position float64
}

type shapebase struct {
	point
}

type circle struct {
	shapebase
	radius float64
}

func main() {
	// 正确的方式:使用完整的字段路径
	p := &circle{
		shapebase: shapebase{
			point: point{
				position: 3.0,
			},
		},
		radius: 5.0,
	}
	
	fmt.Printf("Position: %v, Radius: %v\n", p.position, p.radius)
	// 输出: Position: 3, Radius: 5
}

或者,你也可以使用嵌套的初始化方式:

// 另一种写法
p := &circle{
	shapebase: shapebase{
		point{position: 3.0},
	},
	radius: 5.0,
}

错误信息"无法在类型为 circle 的结构体字面量中使用被提升的字段 shapebase.point.position"表明你试图直接访问多层嵌套的被提升字段。在结构体字面量初始化时,必须按照完整的嵌入层级来指定字段。

虽然在使用结构体字段时可以直接访问被提升的字段(如 p.position),但在初始化时,必须显式地指定完整的嵌入结构体路径。

回到顶部