Файл Yaml для разбора структуры (перевода) в Golang - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь создать функцию перевода для моего веб-приложения. В моем приложении несколько пакетов. Каждый пакет (каталог) содержит папку перевода и файлы yaml внутри. Но у меня проблема с анализом и назначением его сообщениям.

en.yaml

msgLogin : "You've login successfully"

msgProducts:
  0: "You don't have any product."
  1: "You have %d product."
  2: "You have %d products."

errLogin: "Wrong password or username"

мой код:

type TranslationEntry struct {
    Key struct {
        Value interface{}
    }
}

func parseTranslations(dir string) {
    files, _ := ioutil.ReadDir(dir)

    for _, f := range files {
        yamlFile, _ := ioutil.ReadFile(dir + "/" + f.Name())
        var data translation
        if err := yaml.Unmarshal(yamlFile, &data); err != nil {
            return nil, err
        }

        lang := strings.Split(f.Name(), ".")[0]
        switch msg := data.Key.Value.(type) {
        case string:
            message.SetString(language.Make(lang), cast.ToString(data.Key), cast.ToString(data.Key.Value))
        case map[int]string:
            message.Set(language.Make(lang), cast.ToString(data.Key),
                plural.Selectf(1, "%d",
                    "=0", cast.ToString(data.Key.Value["0"]),
                    "=1", cast.ToString(data.Key.Value["1"]),
                    "=2", cast.ToString(data.Key.Value["2"]),
                ))
        }

        translations[lang] = &dictionary{Data: data}
    }
}

I Я полностью заблудился о том, как спроектировать мой файл struct или parse yaml.

Спасибо за продвинутый

1 Ответ

1 голос
/ 30 апреля 2020

Если вы используете библиотеку YAML, я думаю, вы используете (https://godoc.org/gopkg.in/yaml.v2), чтобы создать структуру Golang, которая может использовать Unmarshal для сопоставления с файлом YAML в вашем сообщении. может сделать это:

type TranslationEntry struct {
    MsgLogin string `yaml:"msgLogin"`
    MsgProducts map[int]string `yaml:"msgProducts"`
    ErrLogin string `yaml:"errLogin"`
}

Вещи внутри `` после объявлений полей называются тегами. Это то, как имена полей обычно указываются при отображении между некоторым типом данных и структурой Golang (в моем случае обычно я сопоставляю структуру с JSON, но я также сделал YAML). Если вы используете тот же синтаксический анализатор YAML, о котором я упоминал выше, это то, как он работает.

В основном текст в двойных кавычках - это ключ YAML, в который будет отображаться ваше поле структуры. В приведенном выше коде единственная разница между именем ключа YAML и именем поля структуры заключается в использовании заглавных букв, но здесь приведен пример использования совершенно других имен:

type ExampleStruct struct {
    MyAbcField string `yaml:"abc"`
}

Это установит значение MyAbcField в "my data" при использовании Unmarshal с ExampleStruct и следующим YAML:

abc: "my data"

Это позволяет вам создать Golang структуру, которая соответствует, как вы решите структурировать свой YAML.

Вот Мой код выше в Go Детская площадка: https://play.golang.org/p/Q9FvNsw-BOx

Теперь, если вы не можете исправить структуру для ваших файлов YAML, вы также можете анализировать вложенные карты. Вы можете сделать это, передав переменную типа interface{} (пустой интерфейс) в Unmarshal вместо struct. Тем не менее, это требует большого количества шаблонов, потому что вам нужно будет делать утверждения типа для доступа к вашим данным. Поэтому я рекомендую вместо этого использовать фиксированную структуру, если вы абсолютно не можете ее избежать.

Вот пример, где я анализирую опубликованную вами YAML, а затем получаю поле msgLogin:

var data interface{}
if err := yaml.Unmarshal([]byte(yamlFile), &data); err != nil {
    // handle error
}

// a type assertion that data is a map is needed in order to get keys or iterate
topLevel, ok := data.(map[interface{}]interface{}) 
if !ok {
    // handle error
}

fmt.Println(topLevel["msgLogin"])

И вот Go Playground моего примера структуры изменено, чтобы вместо этого использовать синтаксический анализ на вложенной карте: https://play.golang.org/p/ERBjClSazkz

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...