如何在Go语言中将普通结构体复制到同字段嵌套结构体
问题描述
我需要用Go语言自动化创建JIRA故事,已经完成嵌套JSON与Go结构体的映射并成功创建故事。现在想把简单输入JSON映射得到的普通结构体,复制到字段相同的嵌套结构体中。
输入示例
输入JSON:
{ "project": "cdo", "summary": "sample test story", "issueType": "Story", "userStory" : "this is jira", "assignee": "pradnya.shinde", "teamOwner" : "TEAM-59", "productOwner": "alex.anguiano" }
对应的普通结构体:
type InputJson struct { Project string `json:"project"` Summary string `json:"summary"` Issuetype string `json:"issueType"` UserStory string `json:"userStory"` Assignee string `json:"assignee"` TeamOwner string `json:"teamOwner"` ProductOwner string `json:"productOwner"` }
需要复制到的嵌套结构体:
type JiraCreateStory struct { Fields struct { Project struct { Key string } Summary string Issuetype struct { Name string } UserStory string Assignee struct { Name string } ProductOwner struct { Name string } TeamOwner string } }
请问有没有简洁的代码实现方式?
解决方案
1. 直接字段赋值(最直观简洁)
如果字段数量不多,手动赋值是最清晰且性能最优的方式,无需额外依赖:
func mapInputToJira(input InputJson) JiraCreateStory { var jira JiraCreateStory jira.Fields.Project.Key = input.Project jira.Fields.Summary = input.Summary jira.Fields.Issuetype.Name = input.Issuetype jira.Fields.UserStory = input.UserStory jira.Fields.Assignee.Name = input.Assignee jira.Fields.ProductOwner.Name = input.ProductOwner jira.Fields.TeamOwner = input.TeamOwner return jira }
2. 反射批量处理(适配字段扩展)
如果后续字段可能频繁增减,不想重复修改赋值逻辑,可以用反射批量映射:
import "reflect" func mapWithReflection(input InputJson) JiraCreateStory { var jira JiraCreateStory inputVal := reflect.ValueOf(input) fieldsVal := reflect.ValueOf(&jira.Fields).Elem() for i := 0; i < inputVal.NumField(); i++ { inputField := inputVal.Type().Field(i) inputFieldVal := inputVal.Field(i) fieldsField := fieldsVal.FieldByName(inputField.Name) if !fieldsField.IsValid() { continue } // 处理嵌套结构体字段(优先匹配Name,再匹配Key) if fieldsField.Kind() == reflect.Struct { var targetField reflect.Value if f := fieldsField.FieldByName("Name"); f.IsValid() { targetField = f } else if f := fieldsField.FieldByName("Key"); f.IsValid() { targetField = f } if targetField.IsValid() && targetField.CanSet() { targetField.Set(inputFieldVal) } } else { // 普通字段直接赋值 if fieldsField.CanSet() { fieldsField.Set(inputFieldVal) } } } return jira }
3. 优化结构体定义(长期易维护)
如果允许调整结构体结构,抽离子结构体并添加转换方法,能让代码更易读易维护:
// 抽离JIRA接口所需的子结构体 type JiraProject struct { Key string } type JiraIssueType struct { Name string } type JiraUser struct { Name string } type JiraFields struct { Project JiraProject Summary string Issuetype JiraIssueType UserStory string Assignee JiraUser ProductOwner JiraUser TeamOwner string } type JiraCreateStory struct { Fields JiraFields } // 给InputJson添加转换方法 func (i InputJson) ToJiraCreateStory() JiraCreateStory { return JiraCreateStory{ Fields: JiraFields{ Project: JiraProject{Key: i.Project}, Summary: i.Summary, Issuetype: JiraIssueType{Name: i.Issuetype}, UserStory: i.UserStory, Assignee: JiraUser{Name: i.Assignee}, ProductOwner: JiraUser{Name: i.ProductOwner}, TeamOwner: i.TeamOwner, }, } }
使用时直接调用input.ToJiraCreateStory()即可完成转换。
内容的提问来源于stack exchange,提问作者Pradnya Shinde
相关产品推荐
相关产品推荐

