刚刚学习到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": []
    }
  ]
}