Golang中如何创建嵌套结构体
Golang中如何创建嵌套结构体 我想创建一个嵌套结构体。我不知道子对象的深度。
示例:我想在运行时创建菜单,子菜单数量没有限制。
示例 根节点 M1 M11 M111 M12 M121 M2 M21 M211 M2111 M212 M2121 M3 M4
如何实现这个功能
是的,我知道,但如何深入到子层级。
我知道必须使用递归,但我的问题是
menu[0].item[0] 我该如何以编程方式实现它
我可以定义最多 5 个层级
packs: 我知道我必须使用递归,但我的问题是 menu[0].item[0] 我该如何通过编程方式实现它
这……在我看来不是一个问题。你是在问如何创建/定义你的结构体吗?还是在问如何索引到子项?只要你是在递归地显示它们,那么你有多少层级都无关紧要。
在数据表中,应该存在价格和图标字段吗?我的意思是,原始的数据表结构是:
type MenuItem struct {
Id string
ParentId string
Name string
Price float64
Icon string
}
如果是这样,那么你只需要在该结构体中添加一个 items 切片:
type MenuItem struct {
Id string
ParentId string
Name string
Price float64
Icon string
Items []MenuItem
}
有些条目没有价格和图标(上层父节点),因此你可以在结构体上添加一些标签:
type MenuItem struct {
Id string `json:"id,omitempty"`
ParentId string `json:"-"`
Name string `json:"name,omitempty"`
Price float64 `json:"price,omitempty"`
Icon string `json:"icon,omitempty"`
Items []MenuItem `json:"items,omitempty"`
}
现在你需要一个函数,该函数返回给定 id 对应的 items 切片,如果该条目没有子项,则返回一个空切片。
func setChildren(menuItems []MenuItem, parentId string) []MenuItem) {
result := make([]MenuItem,0)
for _, mi := range menuItems {
if mi.ParentId == parentId {
result = append(result, mi)
}
}
return result
}
希望对你有帮助!!!
你好,
我有以下表格。
myid parentid menu_name 1 0 Video Players 2 0 Televisions 11 1 HD Video Player 12 1 CD player 13 1 USB player 21 2 SuperLCD 42 22 2 SuperLED 42 23 2 SuperLED 50 24 2 SuperLCD 55 (Not available) 25 2 SuperLCD 70 111 11 Video1 112 11 Video2 1111 111 Video111 1112 111 Video112
我想要这种类型的JSON对象
[{
id: '1',
name: 'Video Players',
items: [{
id: '1_1',
name: 'HD Video Player',
price: 220,
icon: 'images/products/1.png',
}, {
id: '1_2',
name: 'SuperHD Video Player',
icon: 'images/products/2.png',
price: 270,
}],
}, {
id: '2',
name: 'Televisions',
items: [{
id: '2_1',
name: 'SuperLCD 42',
icon: 'images/products/7.png',
price: 1200,
}, {
id: '2_2',
name: 'SuperLED 42',
icon: 'images/products/5.png',
price: 1450,
}, {
id: '2_3',
name: 'SuperLED 50',
icon: 'images/products/4.png',
price: 1600,
}, {
id: '2_4',
name: 'SuperLCD 55 (Not available)',
icon: 'images/products/6.png',
price: 1350,
disabled: true,
}, {
id: '2_5',
name: 'SuperLCD 70',
icon: 'images/products/9.png',
price: 4000,
}],
}, {
id: '3',
name: 'Monitors',
items: [{
id: '3_1',
name: '19"',
items: [{
id: '3_1_1',
name: 'DesktopLCD 19',
icon: 'images/products/10.png',
price: 160,
}],
}, {
id: '3_2',
name: '21"',
items: [{
id: '3_2_1',
name: 'DesktopLCD 21',
icon: 'images/products/12.png',
price: 170,
}, {
id: '3_2_2',
name: 'DesktopLED 21',
icon: 'images/products/13.png',
price: 175,
}],
}],
}, {
id: '4',
name: 'Projectors',
items: [{
id: '4_1',
name: 'Projector Plus',
icon: 'images/products/14.png',
price: 550,
}, {
id: '4_2',
name: 'Projector PlusHD',
icon: 'images/products/15.png',
price: 750,
}],
}]
我已经尝试了所有选项。我无法在运行时创建包含这些字段的数组。
在Go中可以通过递归结构体实现嵌套结构体,深度不受限制。这里给出两种常见实现方式:
方法1:使用指针切片实现树形结构
type MenuItem struct {
Name string
Children []*MenuItem
}
// 创建示例菜单
func createMenu() *MenuItem {
root := &MenuItem{Name: "根节点"}
m1 := &MenuItem{Name: "M1"}
m11 := &MenuItem{Name: "M11"}
m111 := &MenuItem{Name: "M111"}
m12 := &MenuItem{Name: "M12"}
m121 := &MenuItem{Name: "M121"}
m11.Children = []*MenuItem{m111}
m1.Children = []*MenuItem{m11, m12}
m12.Children = []*MenuItem{m121}
m2 := &MenuItem{Name: "M2"}
m21 := &MenuItem{Name: "M21"}
m211 := &MenuItem{Name: "M211"}
m2111 := &MenuItem{Name: "M2111"}
m212 := &MenuItem{Name: "M212"}
m2121 := &MenuItem{Name: "M2121"}
m211.Children = []*MenuItem{m2111}
m21.Children = []*MenuItem{m211, m212}
m212.Children = []*MenuItem{m2121}
m2.Children = []*MenuItem{m21}
root.Children = []*MenuItem{m1, m2,
&MenuItem{Name: "M3"},
&MenuItem{Name: "M4"}}
return root
}
// 遍历菜单
func printMenu(menu *MenuItem, depth int) {
indent := strings.Repeat(" ", depth)
fmt.Printf("%s%s\n", indent, menu.Name)
for _, child := range menu.Children {
printMenu(child, depth+1)
}
}
方法2:运行时动态构建嵌套结构
type DynamicMenu struct {
Name string
Children []DynamicMenu
}
// 运行时添加子菜单
func (m *DynamicMenu) AddChild(name string) *DynamicMenu {
child := DynamicMenu{Name: name}
m.Children = append(m.Children, child)
return &m.Children[len(m.Children)-1]
}
// 使用示例
func buildMenuDynamically() DynamicMenu {
root := DynamicMenu{Name: "根节点"}
m1 := root.AddChild("M1")
m11 := m1.AddChild("M11")
m11.AddChild("M111")
m12 := m1.AddChild("M12")
m12.AddChild("M121")
m2 := root.AddChild("M2")
m21 := m2.AddChild("M21")
m211 := m21.AddChild("M211")
m211.AddChild("M2111")
m212 := m21.AddChild("M212")
m212.AddChild("M2121")
root.AddChild("M3")
root.AddChild("M4")
return root
}
// 查找并添加子菜单
func (m *DynamicMenu) FindAndAdd(parentName, childName string) bool {
if m.Name == parentName {
m.AddChild(childName)
return true
}
for i := range m.Children {
if m.Children[i].FindAndAdd(parentName, childName) {
return true
}
}
return false
}
方法3:使用map实现快速查找
type MenuNode struct {
ID string
Name string
Children map[string]*MenuNode
}
func NewMenuNode(id, name string) *MenuNode {
return &MenuNode{
ID: id,
Name: name,
Children: make(map[string]*MenuNode),
}
}
func (m *MenuNode) AddChild(id, name string) *MenuNode {
child := NewMenuNode(id, name)
m.Children[id] = child
return child
}
// 构建示例菜单
func buildMenuWithMap() *MenuNode {
root := NewMenuNode("root", "根节点")
m1 := root.AddChild("m1", "M1")
m11 := m1.AddChild("m11", "M11")
m11.AddChild("m111", "M111")
m12 := m1.AddChild("m12", "M12")
m12.AddChild("m121", "M121")
return root
}
JSON序列化示例
type Menu struct {
Title string `json:"title"`
Children []Menu `json:"children,omitempty"`
}
func createJSONMenu() Menu {
return Menu{
Title: "根节点",
Children: []Menu{
{
Title: "M1",
Children: []Menu{
{
Title: "M11",
Children: []Menu{
{Title: "M111"},
},
},
{
Title: "M12",
Children: []Menu{
{Title: "M121"},
},
},
},
},
{Title: "M2"},
{Title: "M3"},
{Title: "M4"},
},
}
}
// 转换为JSON
func menuToJSON() string {
menu := createJSONMenu()
data, _ := json.MarshalIndent(menu, "", " ")
return string(data)
}
这些实现方式都支持无限深度嵌套,可以根据具体需求选择使用切片、map或直接递归结构体。方法1和方法2更接近传统的树形结构,方法3适合需要快速查找节点的场景。


