首页 > 文章列表 > Golang: 从解析的映射接口{}中删除 YAML 条目

Golang: 从解析的映射接口{}中删除 YAML 条目

286 2024-03-01
问题内容

我正在编写一些测试,在从 yaml 文件加载应用程序配置时需要检查不同的错误条件。由于 yaml 文件相当长,我的方法是从磁盘上的文件读取完整的 yaml 内容,将其内容解组到变量,从生成的 map[interface{}]interface{} 动态删除一些部分在它们的字符串键上,最后将其编组并将内容写入磁盘上的另一个文件,该文件将用作文本输入。也就是说,我在尝试从未编组的 yaml 中删除部分时遇到了问题。下面是我的代码:

func getYAMLWithoutSection(t *testing.T, section string) map[interface{}]interface{} {
    t.Helper()

    yml := unmarshalYAML(t, getYAMLContentFromFile(t))
    var tmp interface{}
    tmp = yml

    keys := strings.Split(section, ".")
    for _, key := range keys {
        tmp = tmp.(map[interface{}]interface{})[key]
    }

    tmp = nil

    return yml
}

// Reads file from disk and returns its content
func getYAMLContentFromFile(t *testing.T) []byte {
    /* ... */
}

func unmarshalYAML(t *testing.T, ymlIn []byte) map[interface{}]interface{} {
    /* ... */
}

这不起作用,因为最终, tmp var 包含目标 yaml 部分的值而不是其内存地址(其类型是 interface{},而不是指针),所以当我设置它到 nil 它对它最终返回的原始 yml 变量中的值没有影响。我尝试过不同的方法,例如将 tmp 的类型切换为 *interface{},但没有成功,而且我不知道执行此操作的正确方法是什么。


正确答案


我终于找到了实现我正在寻找的目标的方法(动态编辑包含未编组的 yaml 的嵌套映射)。这就是我的代码现在的样子:

func getYAMLWithoutSection(t *testing.T, section string) map[interface{}]interface{} {
    t.Helper()

    yml := unmarshalYAML(t, getConfigFileContent(t))
    tmp := yml

    keys := strings.Split(section, ".")
    nKeys := len(keys) - 1
    for i, key := range keys {
        if i == nKeys {
            tmp[key] = nil
            break
        }

        tmp = tmp[key].(map[interface{}]interface{})
    }

    return yml
}

事情是在原始版本中(我在问题中发布的那个)我使用的是 tmp 类型为 interface{} 的变量,所以每次我为该变量分配子图时,其内容都会复制到其中并删除此变量上的键(或修改其值)对原始 yml 没有影响。不过,在这个版本中,我将 tmp 切换为映射 map[interface{}]interface{},并且考虑到 go 中的映射是引用类型,因此对该变量的每一次修改实际上都会反映在 tmp 上。