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

自定义YAML Marshal方法未触发,期望生成双引号格式YAML

问题原因分析
  1. 自定义MarshalYAML返回值逻辑错误:你当前的MarshalYAML方法返回拼接后的字符串,yaml库会将这个字符串视为普通标量值,自动在外层添加单引号包裹,而非解析为嵌套的YAML映射结构,导致期望的缩进和键值对格式无法实现。
  2. 重复添加引号:测试代码中传入的"\"{{ somevar }}\""本身已包含转义双引号,后续自定义方法又额外添加双引号,最终导致输出出现""{{ somevar }}""的重复引号问题。
  3. 方法不符合yaml库序列化规则:yaml库要求自定义MarshalYAML返回可被序列化为YAML的结构(如map、struct或yaml.Node),而非直接返回字符串形式的YAML片段。
解决方案

我们需要修改MarshalYAML方法,让它返回yaml库可识别的映射结构,并控制字符串值使用双引号包裹。以下是基于gopkg.in/yaml.v3的实现(v2版本逻辑类似,仅Style常量名称略有差异):

修正后的代码

类型定义与自定义MarshalYAML方法

import (
    "gopkg.in/yaml.v3"
)

type SetFactTask struct {
    Name   string    `yaml:"name"`
    Module FactValue `yaml:"ansible.builtin.set_fact"`
}

type FactValue map[string]string

func (f FactValue) MarshalYAML() (interface{}, error) {
    // 创建映射类型的yaml节点
    var node yaml.Node
    node.Kind = yaml.MappingNode

    for k, v := range f {
        // 构建键节点
        key := yaml.Node{Kind: yaml.ScalarNode, Value: k}
        // 构建值节点,强制使用双引号格式
        value := yaml.Node{Kind: yaml.ScalarNode, Value: v, Style: yaml.DoubleQuotedStyle}
        
        node.Content = append(node.Content, &key, &value)
    }

    return &node, nil
}

修正测试代码

移除输入值中的多余转义引号,直接传入原始字符串:

foo := modules.SetFactTask{
    Name: "foo",
    Module: modules.FactValue{
        "foo": "{{ somevar }}",
    },
}

output, err := yaml.Marshal(foo)
if err != nil {
    panic(err)
}
fmt.Printf("%s\n", output)

预期输出

name: foo
ansible.builtin.set_fact:
  foo: "{{ somevar }}"
关键说明
  • 通过返回yaml.Node并指定Kind为MappingNode,yaml库会将其解析为嵌套的键值对结构,而非普通字符串。
  • 给值节点设置Style: yaml.DoubleQuotedStyle,强制字符串使用双引号包裹,满足格式需求。
  • 测试代码中不再提前转义引号,避免重复添加导致的格式错误。

内容的提问来源于stack exchange,提问作者user17036156

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 16:30:24