«Go»: чтение ini-файлов
Мне тут для программы на языке «Go» понадобился простой парсер
Кстати говоря, я сильно облегчил себе жизнь, когда написал небольшой
#!/bin/bash
NAME=$1
if [ -f "$NAME" ]; then
TMPNAME=`mktemp -t go.XXXXXXX`
shift
6g -I. -o $TMPNAME.6 $NAME && 6l -L. -o $TMPNAME $TMPNAME.6 && $TMPNAME $*
rm -f $TMPNAME.6 $TMPNAME >/dev/null 2>&1
else
echo "Error: '$NAME' is not found."
fiСам модуль выглядит вот так (и называется «ini»):
package ini
import (
"os"
"bufio"
"strings"
)
type inisection map[string]string
type inifile map[string]inisection
func ParseFile(name string) inifile {
f, err := os.OpenFile(name, os.O_RDONLY, 0666)
if err != nil {
return nil
}
defer f.Close()
r := bufio.NewReader(f)
one := inisection{} // одна, текущая секция
ini := inifile {} // все секции
section := "" // текущее название секции
for {
line, err := r.ReadString('\n')
if err != nil {
break
}
chunks := strings.Split(strings.TrimRight(line, "\r\n"), "=", 3)
if len(chunks) == 2 {
key, value := strings.Trim(chunks[0], "\t "), strings.Trim(chunks[1], "\t ")
last := len(value) - 1
if last > 0 && value[0] == '"' && value[last] == '"' {
value = string(value[1:last])
}
one[key] = string(value)
} else {
last := len(chunks[0]) - 1
if chunks[0][0] == '[' && chunks[0][last] == ']' {
ini[section] = one
one = inisection{}
section = string(chunks[0][1:last])
}
}
}
// «поджимаем хвост», поскольку предыдущая секция попадает в map
// только когда появляется следующая, последнюю нужно перекладывать «руками»
if len(one) > 0 {
ini[section] = one
}
return ini
}Модули пишутся очень просто — достаточно объявить как он будет называться (в директиве «package») и можно его подключать через «import». В «Go» модуль экспортирует всё, что начинается с большой буквы.
Мой модуль экспортирует единственную функцию — ParseFile, принимающую на вход имя файла, на выходе будет ассоциативный массив ассоциативных массивов (map of maps), ключами верхнего уровня является имя секции (если отсутствует, то имя пустое), ключами второго уровня — ключи
Комментарии 12
Выглядит хоть и правильно, но страшновато :) Кстати,
Вообще, я думал, что не знаю, пока не вспомнил, что в Пайтоне ассоциативный массив называется «словарь».
И я вспомнил почему меня всё тянет назвать ассоциативный массив хешем.
Ну вот и Go for App Engine.
http://blog.golang.org/2011/05/go-and-goog … ngine.html
Но лучше узнать в гугл групсах.
А вообще интересно вырастет ли из Голанга конкурент Яве для хайлоад
Комментарий для rodem:
Значит программы придётся проверять достаточно часто.
На Гоу сильно сложнее писать, чем на Яве.
if chunks[0][0] == '[' && chunks[0][last] == ']' {
if len(chunks[0]) — 1 > 0 && chunks[0][0] == '[' && chunks[0][last] == ']' {