首先,我建议阅读此相关的问题:How to handle configuration in Go
接下来,我真的会考虑将在另一种格式的配置。因为你提出的不是一个标准。它接近Java's property file format (.properties
),但即使属性文件可能包含Unicode序列,因此您的代码不是有效的格式解析器,因为它根本不处理Unicode序列。
相反,我会建议使用JSON,因此您可以使用Go或任何其他语言轻松解析它,并且有很多编辑JSON文本的工具,并且它仍然是人性化的。
使用JSON格式,将其解码为map
只是一个函数调用:json.Unmarshal()
。它看起来是这样的:
text := `{"Var1":"Value1", "Var2":"Value2", "Var3":"Value3"}`
var m map[string]string
if err := json.Unmarshal([]byte(text), &m); err != nil {
fmt.Println("Invalid config file:", err)
return
}
fmt.Println(m)
输出(尝试在Go Playground):
map[Var1:Value1 Var2:Value2 Var3:Value3]
的json
包将处理格式化和逃避你,所以你不必担心任何那些。它也会检测并报告错误。此外,JSON更加灵活,您的配置可能包含数字,文本,数组等。所有这些仅仅因为您选择了JSON格式而来“免费”。
另一种常用的配置格式是YAML,但Go标准库不包含YAML分析器。请参阅执行github.com/go-yaml/yaml
。
如果您不想更改格式,那么我只会使用您发布的代码,因为它完全按照您希望的方式执行:逐行处理输入,并从一对name = value
解析对每一行。 它以一种明确而明显的方式做到这一点。使用CSV或任何其他阅读器为此目的是不好的,因为它们隐藏了底层的内容(他们故意并正确地隐藏了格式特定的细节和转换)。一个CSV阅读器是一个CSV阅读器第一个;即使您更改了制表符/逗号符号:它将将解释某些转义序列,并可能会给您不同于您在纯文本编辑器中看到的数据。从您的角度来看,这是一种意想不到的行为,但嘿,您的输入是CSV格式的而不是,但您要求读者将其解释为为 CSV!
我想添加到您的解决方案中的一个改进是使用bufio.Scanner
。它可以用于逐行读取输入,并处理不同样式的换行符序列。它可能看起来像这样:
text := `Var1=Value1
Var2=Value2
Var3=Value3`
scanner := bufio.NewScanner(strings.NewReader(text))
m := map[string]string{}
for scanner.Scan() {
parts := strings.Split(scanner.Text(), "=")
if len(parts) == 2 {
m[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
}
}
if err := scanner.Err(); err != nil {
fmt.Println("Error encountered:", err)
}
fmt.Println(m)
输出是一样的。试试Go Playground。
使用bufio.Scanner
还有另一个优点:bufio.NewScanner()
接受io.Reader
,即“所有东西都是字节源”的通用接口。这意味着如果您的配置存储在一个文件中,您甚至不需要将所有配置读入内存,只需打开该文件即可与os.Open()
返回值*os.File
也实现io.Reader
,因此您可以直接将*os.File
值传递到bufio.NewScanner()
(并且因此bufio.Scanner
将从文件中读取,而不是像上面的示例中那样从内存缓冲区中读取)。
如果它做的工作,我不会担心它。 Go不是关于优雅的代码,而是关于工作代码...... – RickyA
也就是说,在访问它之前('tmp [0]'),我会放一个测试'如果len(tmp)> = 2',因为那可能会失败。 – RickyA
@RickyA非常好的一点,我其实没有真的把任何错误检查在那里。将它添加到我的工作中,谢谢。 – Mikey