Go模板中使用if-else条件动态生成函数签名

在go模板中遍历结构体字段并根据字段值(如是否为null)动态生成不同格式的函数定义,可借助`{{if}}`和`{{else}}`实现分支逻辑,结合变量引用与类型插值完成代码生成。

Go模板原生支持条件判断语法 {{if pipeline}} ... {{else}} ... {{end}},适用于根据数据结构中的字段值(如 nil 或空值)生成差异化内容。针对你的 resourceActions 映射结构,关键在于:正确遍历键值对、识别 input 字段是否为空(Go模板中 null 通常映射为 Go 的 nil 或零值),并据此插入不同函数签名

假设你已将 JSON 数据反序列化为 Go 结构体(例如 map[string]struct{ Input, Output *string }),并在模板中通过 .resourceActions 访问。注意:Go 模板中 nil 指针、空字符串 ""、nil slice/map 等均会被 {{if}} 视为 false;但需确保字段类型设计合理(推荐用指针类型如 *string 表示可为空字段)。

以下为完整、健壮的模板写法示例:

{{range $key, $action := .resourceActions}}
    {{if $action.Input}}
        func (c *Container) {{$key}}(input *{{$action.Input}}) *{{$.schema.Id}} {
            // 实现逻辑
        }
    {{else}}
        func (c *Container) {{$key}}() *{{$.schema.Id}} {
            // 实现逻辑
        }
    {{end}}
{{end}}

关键说明:

  • {{range $key, $action := .resourceActions}} 正确迭代 map 的键(如 "update")和值(对应 action 结构体);
  • {{if $action.Input}} 判断 Input 字段是否非 nil(Go 模板中 nil 指针为 falsy);
  • {{$action.Input}} 直接输出其字符串值(如 "instanceStop"),无需额外解引用;
  • {{$.schema.Id}} 使用 $ 显式访问根作用域的 schema.Id,避免在 range 内部作用域丢失上下文;
  • 模板中不写分号,Go 语法由生成器保证;缩进仅为可读性,实际输出可按需调整。

⚠️ 注意事项:

  • 若 Input 字段是 string 类型(而非 *string),空字符串 "" 也会被 {{if}} 视为 false,此时需改用 {{if ne $action.Input ""}} 显式比较;
  • 确保传入模板的数据结构中 Input 字段确实为 nil(JSON 中 "input": null → Go *string = nil),而非 "input": "";
  • 函数体占位符(如 // 实现逻辑)可根据需要替换为真实调用,例如 return c.do{{$key}}(input);
  • 若需生成方法集到特定 receiver 类型(如 *Container),请确保 schema.Id 值合法(如 "Container"),且首字母大写以导出。

通过该模式,你可安全、清晰地为每个资源操作生成符合 Go 语法规范的函数声明,实现配置驱动的代码生成流程。