You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:40:33