Как получить доступ к определенным элементам в массиве из Viper

#go #yaml #viper-go

#Вперед #yaml #viper-go

Вопрос:

У меня есть файл yaml, похожий на следующий:

 ComplexItemList:
- Name: First Complex item
  Date: Whenever
  StructItemList:
  - Name: blah
    Data1: 0
    Data2: Silly
  - Name: Yaddah
    Data1: 12
    Data2: Blah-blah-blah
- Name: Second Complex item
  Date: Yesterday
  StructItemList:
  - Name: blah
    Data1: 0
    Data2: Silly
  - Name: Yaddah
    Data1: 12
    Data2: Blah-blah-blah
  

Вот простая версия моего кода:

 package main

import (
    "fmt"

    "github.com/spf13/viper"
)

type StructItem struct {
    Name  string `yaml:"Name"`
    Data1 int    `yaml:"Data1"`
    Data2 string `yaml:"Data2"`
}

type ComplexItem struct {
    Name           string       `yaml:"Name"`
    Date           string       `yaml:"Date"`
    StructItemList []StructItem `yaml:"StructItemList,mapstructure"`
}

type TestConfig struct {
    Version         string        `yaml:"Version"`
    ComplexItemList []ComplexItem `yaml:"ComplexItemList,mapstructure"`
}

func main() {
    viper.SetConfigName("simple1") // name of config file (without extension)
    viper.SetConfigType("yaml")    // REQUIRED if the config file does not have the extension in the name
    viper.AddConfigPath(".")
    err := viper.ReadInConfig() // Find and read the config file
    if err != nil {             // Handle errors reading the config file
        panic(fmt.Errorf("Fatal error config file: %s n", err))
    }

    test1 := viper.Get("ComplexItemList")
    fmt.Printf("test1:n%#vn", test1)
    // while I can easily unmarshal the information into a complex struct,
    // updating the file contents via viper does not seem straight forward.
    // Is there a way to access a specific item in an array using viper dot notation?

    config := TestConfig{}
    viper.Unmarshal(amp;config)
    // is the best way to update Data1 for "First Complex item", just to update the
    // unmarshalled struct then write the whole thing back out?
}
  

Я хочу использовать Viper для чтения файла конфигурации, но я не уверен, как различать «Первый сложный элемент» и «Второй сложный элемент» при использовании методов Get. Нужно ли мне поддерживать состояние начала сложного элемента по мере их поступления?

Комментарии:

1. Пожалуйста, покажите, что вы пробовали.

2. Мне действительно интересно, как сериализовать изменения конфигурации в памяти в файл на диске, поскольку в viper нет метода маршалирования. Я думал, что правильным использованием было бы использовать «viper.Set («x.y.z», значение)», но я не знаю, каким «x.y.z» должно быть в случае массива.

Ответ №1:

Я слишком усложнял ситуацию. Самый простой способ — отменить сопоставление значений, обновить их, а затем установить массив из объекта.

     config := TestConfig{}
    viper.Unmarshal(amp;config)

    config.ComplexItemList[0].StructItemList[0].Data2 = "updated item"
    viper.Set("ComplexItemList", config.ComplexItemList)
  

Или это неправильный способ обработки обновления массива в файле yaml через viper?