Fetching configuration or default value I have two code snippets, doing exactly the same thing and both get the job done: 


use defaults
use from config


Which is cleaner to use in golang and why?

first option:


package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(getShCfg(Cfg{}), "\n================")
    fmt.Println(getShCfg(Cfg{"8MB", "4MB"}), "\n================")
    fmt.Println(getShCfg(Cfg{"8MB", ""}), "\n================")
    fmt.Println(getShCfg(Cfg{"", "4MB"}), "\n================")
}

type Cfg struct { A, B string }

func getShCfg(c Cfg) string {
    var out []string

    la := "l_sh_dit conf_data 7MB"
    lb := "l_sh_dit cert_data 3MB"

    if len(c.A) &gt; 0 {
        out = append(out, "l_sh_dit conf_data " + c.A)
    } else {
        out = append(out, la)
    }
    if len(c.B) &gt; 0 {
        out = append(out, "l_sh_dit cert_data "+c.B)

    } else {
        out = append(out, lb)
    }

    return strings.Join(out, ";\n\r") + ";"

}



second option: 


package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(getShCfg(Cfg{}), "\n================")
    fmt.Println(getShCfg(Cfg{"8MB", "4MB"}), "\n================")
    fmt.Println(getShCfg(Cfg{"8MB", ""}), "\n================")
    fmt.Println(getShCfg(Cfg{"", "4MB"}), "\n================")
}

type Cfg struct { A, B string }

func getShCfg(c Cfg) string {
    out := []string{
        getCfgProp("l_sh_dit conf_data", c.A, "7MB"),
        getCfgProp("l_sh_dit cert_data", c.B, "3MB"),
    }
    return strings.Join(out, ";\n\r") + ";"

}

func getCfgProp(key, val, def string) string {
    if len(val) &gt; 0 {
        return key + " " + val
    }
    return key + " " + def
}




I would prefer the second option as it is more scalable i.e. if there are more than 2 parameters (two if else)  so in this case I'm skipping on another if-else in the code …

But in case there are only 2 parameters, is it worth to create a helper function?  

Also if there is a better/cleaner approach to achieve it with Golang please let me know
None of the above. Rewrite the first option in readable form. For example,

package main

import (
    "fmt"
    "strings"
)

type Cfg struct{ A, B string }

func getShCfg(c Cfg) string {
    var out []string

    msg := "l_sh_dit conf_data "
    if len(c.A) &gt; 0 {
        msg += c.A
    } else {
        msg += "7MB"
    }
    out = append(out, msg)

    msg = "l_sh_dit cert_data "
    if len(c.B) &gt; 0 {
        msg += c.B
    } else {
        msg += "3MB"
    }
    out = append(out, msg)

    return strings.Join(out, ";\n\r") + ";"
}

func main() {
    sep := "\n================"
    for _, cfg := range []Cfg{
        {},
        {"8MB", "4MB"},
        {"8MB", ""},
        {"", "4MB"},
    } {
        fmt.Println(getShCfg(cfg), sep)
    }
}


Output:

l_sh_dit conf_data 7MB;
l_sh_dit cert_data 3MB; 
================
l_sh_dit conf_data 8MB;
l_sh_dit cert_data 4MB; 
================
l_sh_dit conf_data 8MB;
l_sh_dit cert_data 3MB; 
================
l_sh_dit conf_data 7MB;
l_sh_dit cert_data 4MB; 
================


Factoring out common code and data simplifies and highlights the structure of the problem.

To generalize we typically need three to seven cases. We have two. Configuration parameters usually contain a wide range of information and data types and structures. Idle speculation is not useful.

We have safely encapsulated the problem. As we learn more, we can easily revise the code.