英文:
parsing TOML without a known structure
问题
与这个关于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)
英文:
Similar to this question for rust, I want to parse a TOML without having a strong knowledge of the entire structure of the TOML. So, my first attempt based on this reddit discussion was something like this:
# 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)
}
}
}
but that generated an empty output:
map[string]interface {}(nil)
答案1
得分: 1
作为一个可能的解决方案,我提供了以下代码:
package main
import (
"os"
"fmt"
"github.com/BurntSushi/toml"
)
type tomlConfig struct {
Conf map[string]interface{}
}
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]interface{})) {
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]interface{}
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]]
英文:
As a possible solution, I came up with was this below,
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)
}
}
for the config.toml it generated the following output:
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]]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论