解析一个包含哈希表名称的 TOML 文件。

huangapple go评论78阅读模式
英文:

Go unmarshalling a toml which contains a hash table name

问题

使用go语言的toml解析器(https://github.com/BurntSushi/toml),我正在尝试解析以下toml文件:

type (
    fruitSpecs struct {
        Id     int      `toml:"id"`
        Name   string   `toml:"name"`
    }
)
blob := `
[kiwi]
    id = 1234581941
    name = "kiwi"
`
o := &fruitSpecs{}
err := toml.Unmarshal([]byte(blob), o)
fmt.Println(o.Id)

看起来当我使用表格[kiwi]时,无法正确解析它。

如果我删除表格名称,我可以成功获取Id字段。

在尝试成功构建包含数据的整个结构体时,我是否缺少一些封装?

我尝试了以下添加表格名称的方法,但没有任何积极的结果:

type (
    fruitSpecs struct {
        Id     int      `toml:"id"`
        Name   string   `toml:"name"`
    }
    fruits struct {
        fruit fruitSpecs
    }
)
blob := `
[kiwi]
    id = 1234581941
    name = "kiwi"
`
o := &fruitSpecs{}
err := toml.Unmarshal([]byte(blob), o)
fmt.Println(o.Id)

但它报错为:o.Id未定义(类型*fruitSpecs没有字段或方法Id)

英文:

With a toml parser for go (https://github.com/BurntSushi/toml)

I am trying to unmarshall the following toml file:

            type (
				fruitSpecs struct {
					Id     int      `toml:"id"`
					Name   string   `toml:"name"`
				}
			)
			blob := `
			[kiwi]
				id = 1234581941
				name = "kiwi"
			`
			o := &fruitSpecs{}
			err := toml.Unmarshal([]byte(blob), o)
			fmt.Println(o.Id)

It seems like when I use a table [kiwi] It does not seem like I can unmarshall it correctly.

If I remove the table name, I can succesfully grab the Id field.

I am missing some encapsulation when trying to successfully build the whole struct that will hold the data?

I have tried the following to add the table name, but without any positive outcome:

            type (
				fruitSpecs struct {
					Id     int      `toml:"id"`
					Name   string   `toml:"name"`
				}
                fruits struct {
                    fruit fruitSpecs
                }
			)
			blob := `
			[kiwi]
				id = 1234581941
				name = "kiwi"
			`
			o := &fruitSpecs{}
			err := toml.Unmarshal([]byte(blob), o)
			fmt.Println(o.Id)

But it errors with:
o.Id undefined (type *fruitSpecs has no field or method Id)

答案1

得分: 1

更新1:
我已经使用哈希表名称成功解码了它。请参考以下示例以获取更多详细信息:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs `toml:"kiwi"`
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            `
            o := &fruits{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.fruit.Id)

// CLI 输出:
// 1234581941

请注意三个更改:在结构体中添加标签,将变量o指向通用结构体,并使用正确的路径打印id(o.fruit.Id)。

问题在于我需要解析多个表,并且在标签中指定表名是不可行的。

有没有办法告诉burntsushi toml解析器忽略表名并接受来自所有表名的内容?类似于:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs `toml:"*"` // 不按名称过滤,接受每个表名条目
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            [banana]
                id = 9876544312
                name = "banana"
            `
            o := &fruits{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.fruit.Id)
// 期望输出:
// 1234581941
// 9876544312

更新2:
最后,我使用以下代码获取了所有包含Id的字段:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruit map[inteface{}]fruitSpecs
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            [banana]
                id = 9876544312
                name = "banana"
            `
            var o fruit
            err := toml.Decode(blob, &fruit)
            for _, item := range o {
                fmt.Println(item.Id)
            }
// CLI 输出:
// 1234581941
// 9876544312

请注意使用toml.Decode替代toml.Unmarshal,将fruitSpecs的结构生成为映射,并对映射的结构进行迭代。

这就是我解决这个问题的方法。

自由软件。

英文:

UPDATE 1:
I've managed to decode it with a hash table name. See the following example for more details:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs `toml:"kiwi"`
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            `
            o := &fruits{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.fruit.Id)

// CLI Output:
// 1234581941

Please note the three changes, adding the tag into the struct, o variable pointing to the general struct, and printing the id with the correct path (o.fruit.Id)

The problem here is that I need to parse more than one table, and specifying the table name in the tag is not viable.

Is there any way of telling burntsushi toml parse to ignore the table name and accept everything from it? Something like:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruits struct {
                    fruit fruitSpecs `toml:"*"` // Do not filter by name, accept every table name entry
                }
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            [banana]
                id = 9876544312
                name = "banana"
            `
            o := &fruits{}
            err := toml.Unmarshal([]byte(blob), o)
            fmt.Println(o.fruit.Id)
// Desired output:
// 1234581941
// 9876544312

UPDATE 2:
Finally I managed to get all the fields containing Id with the following code:

            type (
                fruitSpecs struct {
                    Id     int      `toml:"id"`
                    Name   string   `toml:"name"`
                }
                fruit map[inteface{}]fruitSpecs
            )
            blob := `
            [kiwi]
                id = 1234581941
                name = "kiwi"
            [banana]
                id = 9876544312
                name = "banana"
            `
            var o fruit
            err := toml.Decode(blob, &fruit)
            for _, item := range o {
                fmt.Println(item.Id)
            }
// CLI Output:
// 1234581941
// 9876544312

Note the changes of using toml.Unmarshall to toml.Decode, generating into a map the struct of fruitSpecs and interating over the mapped struct.

This is how I resolved this issue.

Free software.

huangapple
  • 本文由 发表于 2022年10月17日 02:39:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/74089792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定