Go语言 解析没有已知结构的TOML

f0ofjuux  于 2023-06-19  发布在  Go
关注(0)|答案(1)|浏览(135)

rust的这个问题类似,我想在不了解TOML的整个结构的情况下解析TOML。所以,我基于reddit讨论的第一次尝试是这样的:

# Configuration of Server Control 
[config]
control_server_ipaddr = "0.0.0.0"
control_server_port = 7077

[[module]]
filename = "filename_test1"
execcmd = "execcmd_test1"

[[module]]
filename = "filename_test2"
execcmd = "execcmd_test2"
package main

import (
    "fmt"
    "github.com/BurntSushi/toml"
)

type tomlConfig struct {
    Conf map[string]any
}

func check(e error) {
    if e != nil {
        panic(e)
    }
}

func main() {
    var c tomlConfig
    if _, err := toml.DecodeFile("config.toml", &c); err != nil {
        fmt.Println(err)
        return
    }

        fmt.Printf("%#v\n",c.Conf)

    for k, v := range c.Conf {
        fmt.Printf("%s\n", k)
        switch c := v.(type) {
                case string:
                    fmt.Printf("Item %q is a string, containing %q\n", k, c)
                case float64:
                    fmt.Printf("Looks like item %q is a number, specifically %f\n", k, c)
                default:
                    fmt.Printf("Not sure what type item %q is, but I think it might be %T\n", k, c)
            }
    }   
}

但这会产生一个空输出:

map[string]interface {}(nil)
zlhcx6iw

zlhcx6iw1#

作为一个可能的解决方案,我想到了下面这个,

package main

import (
    "os"
    "fmt"
    "github.com/BurntSushi/toml"
)

type tomlConfig struct {
    Conf map[string]any
}

    
func check(e error) {
    if e != nil {
        panic(e)
    }
}

func isType(a, b interface{}) bool {
    return fmt.Sprintf("%T", a) == fmt.Sprintf("%T", b)
}

func PrintDict(k1 string, v1 interface{}) {
    fmt.Printf("Key:%s\n",k1)
    if isType(v1,  make(map[string]any)) {
        data := v1.(map[string]interface{})
        for k2, v2 := range data {
          PrintDict(k2, v2)
        }
    } else {
       fmt.Printf("Value:%s\n",v1)
    }
}

func main() {
    var Conf map[string]any
        data, err := os.ReadFile("config.toml")
        if err != nil {
                fmt.Printf("ERROR: reading (config.toml).")
                os.Exit(1)
        }
        err=toml.Unmarshal(data, &Conf)

        for k, v := range Conf {
                PrintDict(k, v)
        }
}

对于config.toml,它生成以下输出:

Key:config
Key:control_server_ipaddr
Value:0.0.0.0
Key:control_server_port
Value:%!s(int64=7077)
Key:module
Value:[map[execcmd:execcmd_test1 filename:filename_test1] map[execcmd:execcmd_test2 filename:filename_test2]]

相关问题