3

I have the following code:

package main

import (
    "log"

    "github.com/spf13/viper"
)

func main() {
    viper.SetEnvPrefix("myprefix")
    viper.SetDefault("languages", []string{"french", "spanish"})
    viper.BindEnv("name")
    viper.BindEnv("languages")

    type config struct {
        Name      string
        Languages []string
    }

    var C config

    err := viper.Unmarshal(&C)
    if err != nil {
        log.Fatalln("unable to decode into struct, %v", err)
    }

    log.Println(C)
    log.Println(len(C.Languages))
}

When $MYPREFIX_LANGUAGES is not set the length of C.Languages is 2 (eg the default). When I set $MYPREFIX_LANGUAGES to "english spanish french russian" I get a length of 1. It is just taking the variable as 1 long string, not a slice. How do I get a slice ([]string{"english", "spanish", "french", "russian"}?

Zoyd
  • 3,449
  • 1
  • 18
  • 27
  • Seems like you need to do that manually after unmarshalling. – zerkms Apr 03 '17 at 04:19
  • Apparently it works if you use a config file but not with environmental variables. http://stackoverflow.com/questions/38955605/reading-a-slice-of-maps-with-golang-viper –  Apr 03 '17 at 04:21
  • 1
    Yep, because config files are structured, and environment variables is a collection of strings. – zerkms Apr 03 '17 at 04:21
  • @zerkms please make an answer so I can accept it. –  Apr 03 '17 at 23:33
  • 1
    What's the value for `viper.Get("languages")` ... ? Reason I ask is that I had a quick look at the source for viper and found this line: https://github.com/spf13/viper/blob/master/viper.go#L560 which leads me to believe that what you want can be done... just maybe not by the .`Unmarshall` func. – Charlino Apr 04 '17 at 00:03
  • @Charlino Actually, that is the correct answer. Setting that to true will unmarshall it correctly. Please make an answer. –  Apr 04 '17 at 01:38

1 Answers1

7

Thanks to @Charlino here is the answer:

package main

import (
    "log"

    "github.com/spf13/viper"
)

func main() {
    viper.SetEnvPrefix("myprefix")
    viper.SetTypeByDefaultValue(true)
    viper.SetDefault("languages", []string{"french", "spanish"})
    viper.BindEnv("name")
    viper.BindEnv("languages")

    type config struct {
        Name      string
        Languages []string
    }

    var C config

    err := viper.Unmarshal(&C)
    if err != nil {
        log.Fatalln("unable to decode into struct, %v", err)
    }

    log.Println(C)
    log.Println(len(C.Languages))
}