刚刚学习到Go的接口部分,希望对之前的基础部分(struct、slice、map)做一个简单的总结!
希望各位Go语言方面的大佬给一点意见,非常感谢!!!
编写过程中存在的一些疑惑:
- TreeNode结构中定义的Child()和SetChild()方法都是返回的接口本身,但是在结构体定义以及实现的时候感觉用着有点别扭,没有Java那么顺畅(可能是Go还不熟悉)。。。
package main
import (
"fmt"
"strconv"
)
// TreeNode 节点接口
type TreeNode interface {
// Id 节点ID
Id() int
// Pid 父节点ID
Pid() int
// Name 节点名称
Name() string
// Child 获取子节点切片
Child() *[]*TreeNode
// String 节点打印方法
String() string
}
// BuildTree 构建树结构
func BuildTree(nodes []TreeNode, root int) []TreeNode {
collect := make(map[int]*TreeNode, len(nodes))
for idx, elem := range nodes {
collect[elem.Id()] = &nodes[idx]
}
var result []TreeNode
for key, val := range collect {
if (*val).Pid() == root {
result = append(result, *val)
} else {
*(*collect[(*val).Pid()]).Child() = append(*(*collect[(*val).Pid()]).Child(), collect[key])
}
}
return result
}
// Menu 菜单,实现节点接口以此构建菜单树
type Menu struct {
id int //节点ID
pid int //父节点ID
name string //节点名称
child []*TreeNode //子节点
}
func (menu *Menu) String() string {
ss := "{\"id\": " + strconv.Itoa(menu.id) + ", \"pid\": " + strconv.Itoa(menu.pid) + ", \"name\": \"" + menu.name + "\", \"child\": ["
for idx, elem := range menu.child {
if idx == len(menu.child)-1 {
ss += (*elem).String()
} else {
ss += (*elem).String() + ","
}
}
ss += "]}"
return ss
}
func (menu *Menu) Id() int {
return menu.id
}
func (menu *Menu) Pid() int {
return menu.pid
}
func (menu *Menu) Name() string {
return menu.name
}
// Child 获取当前对象的子节点对象切片,一定要用指针接收器,因为非指针接收器不能修改当前对象
func (menu *Menu) Child() *[]*TreeNode {
return &menu.child
}
func main() {
var list = []TreeNode{
&Menu{1, 0, "一级节点01", []*TreeNode{}},
&Menu{2, 0, "一级节点02", []*TreeNode{}},
&Menu{3, 0, "一级节点03", []*TreeNode{}},
&Menu{11, 1, "二级节点01", []*TreeNode{}},
&Menu{14, 1, "二级节点04", []*TreeNode{}},
&Menu{15, 1, "二级节点05", []*TreeNode{}},
&Menu{12, 2, "二级节点02", []*TreeNode{}},
&Menu{16, 2, "二级节点06", []*TreeNode{}},
&Menu{13, 3, "二级节点03", []*TreeNode{}},
&Menu{21, 11, "三级节点01", []*TreeNode{}},
&Menu{22, 11, "三级节点02", []*TreeNode{}},
&Menu{23, 14, "三级节点03", []*TreeNode{}},
&Menu{24, 15, "三级节点04", []*TreeNode{}},
&Menu{25, 16, "三级节点05", []*TreeNode{}},
&Menu{26, 12, "三级节点06", []*TreeNode{}},
&Menu{27, 12, "三级节点07", []*TreeNode{}},
}
tree := BuildTree(list, 0)
for _, node := range tree {
fmt.Printf("%v\n", node.String())
}
}
执行结果(Json格式化的时候请使用正则将\n换行符去除,这个输出自动加了换行符,目前不晓得原理。。。):
使用Json格式化后的结果:
{
"id": 1,
"pid": 0,
"name": "一级节点01",
"child": [
{
"id": 14,
"pid": 1,
"name": "二级节点04",
"child": [
{
"id": 23,
"pid": 14,
"name": "三级节点03",
"child": []
}
]
},
{
"id": 15,
"pid": 1,
"name": "二级节点05",
"child": [
{
"id": 24,
"pid": 15,
"name": "三级节点04",
"child": []
}
]
},
{
"id": 11,
"pid": 1,
"name": "二级节点01",
"child": [
{
"id": 21,
"pid": 11,
"name": "三级节点01",
"child": []
},
{
"id": 22,
"pid": 11,
"name": "三级节点02",
"child": []
}
]
}
]
}
{
"id": 2,
"pid": 0,
"name": "一级节点02",
"child": [
{
"id": 12,
"pid": 2,
"name": "二级节点02",
"child": [
{
"id": 26,
"pid": 12,
"name": "三级节点06",
"child": []
},
{
"id": 27,
"pid": 12,
"name": "三级节点07",
"child": []
}
]
},
{
"id": 16,
"pid": 2,
"name": "二级节点06",
"child": [
{
"id": 25,
"pid": 16,
"name": "三级节点05",
"child": []
}
]
}
]
}
{
"id": 3,
"pid": 0,
"name": "一级节点03",
"child": [
{
"id": 13,
"pid": 3,
"name": "二级节点03",
"child": []
}
]
}