Golang实现中树形结构值丢失问题探讨
Golang实现中树形结构值丢失问题探讨
package main
import (
"encoding/json"
"fmt"
)
type employee struct {
Name string `json:"name"`
Id int `json:"id,omitempty"`
ManagerId int `json:"managerid"`
Reporters []employee `json:"reporters,omitempty"`
}
// type employees struct {
// employees []employee `json:"employee"`
// }
type EmployeeList struct {
employees map[int]employee
root employee
}
func NewEmployeeList() *EmployeeList {
var el EmployeeList
el.employees = make(map[int]employee)
return &el
}
func (el EmployeeList) CreateMap(employeesInfo []employee) {
for _ , emp := range employeesInfo {
e := employee{
Name : emp.Name,
Id: emp.Id,
ManagerId: emp.ManagerId,
}
el.employees[emp.Id] = e
if(emp.ManagerId == 0){
el.root = e
fmt.Println("CreateMap",el.root)
}
}
fmt.Println("CreateMap2",el.root,el.employees)
}
func (el EmployeeList) getReportersById(empId int) []employee {
reporters := []employee{}
for _ , employee := range el.employees {
if(employee.ManagerId == empId){
reporters = append(reporters, employee)
}
}
return reporters
}
func (el EmployeeList) maketree(e employee) {
//e := root
e.Reporters = el.getReportersById(e.Id)
if(true){
fmt.Println("maketree",e.Id,e.Name,e.Reporters)
}
// e.Reporters = reporters
if(len(e.Reporters) == 0){
return
}
for _ , reporterEmployee := range e.Reporters {
el.maketree(reporterEmployee);
}
}
func (el EmployeeList) print(root employee, level int) {
for i:= 0; i<level;i++ {
fmt.Print("\t");
}
fmt.Println(root.Name);
for _, reporter := range root.Reporters {
fmt.Println("Enter");
el.print(reporter, level + 1)
}
}
func main() {
//1. Read JSON File
myJsonString := `[{ "name": "Rob", "id": 7, "managerid": 3 }, { "name": "Rex", "id": 6, "managerid": 2 }, { "name": "Jake", "id": 5, "managerid": 2 }, { "name": "Paul", "id": 4, "managerid": 1 }, { "name": "Oliver", "id": 3, "managerid": 1 }, { "name": "John", "id": 2, "managerid": 1 }, { "name": "Britney", "id": 1, "managerid": 0 }]`
//2. Create class and sent file data
emplist := NewEmployeeList()
rawEmployeesInfo := []employee{}
_ = json.Unmarshal([]byte(myJsonString),&rawEmployeesInfo);
fmt.Println(rawEmployeesInfo);
emplist.CreateMap(rawEmployeesInfo);
//fmt.Println(emplist.employees,emplist.root);
fmt.Println("Main1",emplist.root)
emplist.maketree(emplist.root);
//fmt.Println(emplist.root)
fmt.Println("Main2",emplist.root)
emplist.print(emplist.root,0)
}
运行代码时,在打印树的内容之前,树的值丢失了。有人能告诉我哪里出错了吗?
更多关于Golang实现中树形结构值丢失问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
在CreateMap和maketree方法中,您使用了值接收器,这会导致结构体副本被修改,而不是原始对象。以下是修正后的代码:
package main
import (
"encoding/json"
"fmt"
)
type employee struct {
Name string `json:"name"`
Id int `json:"id,omitempty"`
ManagerId int `json:"managerid"`
Reporters []employee `json:"reporters,omitempty"`
}
type EmployeeList struct {
employees map[int]employee
root employee
}
func NewEmployeeList() *EmployeeList {
var el EmployeeList
el.employees = make(map[int]employee)
return &el
}
// 改为指针接收器
func (el *EmployeeList) CreateMap(employeesInfo []employee) {
for _, emp := range employeesInfo {
e := employee{
Name: emp.Name,
Id: emp.Id,
ManagerId: emp.ManagerId,
}
el.employees[emp.Id] = e
if emp.ManagerId == 0 {
el.root = e
fmt.Println("CreateMap", el.root)
}
}
fmt.Println("CreateMap2", el.root, el.employees)
}
func (el *EmployeeList) getReportersById(empId int) []employee {
reporters := []employee{}
for _, employee := range el.employees {
if employee.ManagerId == empId {
reporters = append(reporters, employee)
}
}
return reporters
}
// 改为指针接收器,并修改为直接操作map中的employee
func (el *EmployeeList) maketree(empId int) {
emp := el.employees[empId]
emp.Reporters = el.getReportersById(empId)
// 更新map中的employee
el.employees[empId] = emp
fmt.Println("maketree", emp.Id, emp.Name, emp.Reporters)
if len(emp.Reporters) == 0 {
return
}
for _, reporter := range emp.Reporters {
el.maketree(reporter.Id)
}
}
func (el *EmployeeList) print(root employee, level int) {
for i := 0; i < level; i++ {
fmt.Print("\t")
}
fmt.Println(root.Name)
for _, reporter := range root.Reporters {
el.print(reporter, level+1)
}
}
func main() {
myJsonString := `[{ "name": "Rob", "id": 7, "managerid": 3 }, { "name": "Rex", "id": 6, "managerid": 2 }, { "name": "Jake", "id": 5, "managerid": 2 }, { "name": "Paul", "id": 4, "managerid": 1 }, { "name": "Oliver", "id": 3, "managerid": 1 }, { "name": "John", "id": 2, "managerid": 1 }, { "name": "Britney", "id": 1, "managerid": 0 }]`
emplist := NewEmployeeList()
rawEmployeesInfo := []employee{}
_ = json.Unmarshal([]byte(myJsonString), &rawEmployeesInfo)
fmt.Println(rawEmployeesInfo)
emplist.CreateMap(rawEmployeesInfo)
fmt.Println("Main1", emplist.root)
// 从根节点开始构建树
emplist.maketree(emplist.root.Id)
// 更新根节点
emplist.root = emplist.employees[emplist.root.Id]
fmt.Println("Main2", emplist.root)
emplist.print(emplist.root, 0)
}
主要修改:
- 将
CreateMap、getReportersById、maketree和print方法的接收器改为指针类型(*EmployeeList) - 修改
maketree方法,直接操作el.employeesmap中的employee对象 - 在
main函数中,构建树后更新根节点引用
这样修改后,树形结构的值就不会丢失了。


