#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?