未调用自定义 yaml marshal 方法

问题描述 投票:0回答:1

我正在尝试创建一个自定义 yaml 编组器,因此引用的字符串会得到双引号,而不是单引号。

我有以下类型/方法(为简洁起见,进行了简化):

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

type FactValue map[string]string

// playing around with various ways to force output to have double quotes, not embedded in single-quotes
func (f FactValue) MarshalYAML() (interface{}, error) {
    sb := strings.Builder{}
    for k, v := range f {
        sb.WriteString(fmt.Sprintf("  %s:", k))
        sb.Write([]byte(`"`))
        sb.WriteString(v)
        sb.Write([]byte(`"`))
    }
    return sb.String(), 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)

我得到这个输出(foo 的值用单引号括起来):

name: foo
ansible.builtin.set_fact: '  foo:""{{ somevar }}""'

这就是我想要的:

name: foo
ansible.builtin.set_fact:
  foo: "{{ somevar }}"

看起来我的 MarshalYAML 方法没有被调用。没有错误或任何东西。

go yaml
1个回答
0
投票

yaml.Marshaller
接口定义了一个可以由类型实现的函数,并且它需要一个指针接收器。将代码更改为以下结果会导致
MarshalYAML
被调用为
FactValue
:

// playing around with various ways to force output to have double quotes, not embedded in single-quotes
func (f *FactValue) MarshalYAML() (interface{}, error) {
    sb := strings.Builder{}
    for k, v := range *f {
        sb.WriteString(fmt.Sprintf("  %s:", k))
        sb.Write([]byte(`"`))
        sb.WriteString(v)
        sb.Write([]byte(`"`))
    }
    return sb.String(), nil
}

在我的测试代码中,返回:

name: foo
ansible.builtin.set_fact:
        foo: '"{{ somevar }}"'
© www.soinside.com 2019 - 2024. All rights reserved.