1

Is there a shorter way to initialize ip2 to empty string if there is only one argument in my variadic function below?

func myvariadic(ip ...string) {
    ip1 := ip[0]
    if len(ip) > 1 { 
        ip2 := ip[1] 
    } else {
        ip2 := ""
        ///...
    }
icza
  • 389,944
  • 63
  • 907
  • 827
irom
  • 3,316
  • 14
  • 54
  • 86

3 Answers3

3

You may simply use:

func myvariadic(ip ...string) {
    ip1, ip2 := ip[0], ""
    if len(ip) > 1 {
        ip2 = ip[1]
    }
    fmt.Println(ip1, ip2)
}

But don't forget that variadic functions may be called with 0 arguments specified / passed as the value for the variadic parameter. What this means is that it is also legal (not a compile-time error) to call myvariadic() with zero arguments, and then even ip[0] will cause a runtime panic.

If your function must receive at least one string and optionally a second, you should change the signature of your function to this:

func myvariadic(ip1 string, ips ...string) {
    ip2 := ""
    if len(ips) > 1 {
        ip2 = ips[1]
    }
    fmt.Println(ip1, ip2)
}

What this guarantees is that 1 string will surely be passed (else it would be a compile-time error). This is also more efficient if only one argument is passed, as no slice allocation will be needed (nil will be used for ips). See more details on this here: Is it possible to trigger compile time error with custom library in golang?

If parameters are always 1 or 2 string values, I'm not sure variadic parameters is justified at all, you may simply use:

func myNonVariadic(ip1, ip2 string) {
    fmt.Println(ip1, ip2)
}

And simply pass the empty string "" at the caller if ip2 is not available.

If you still want to stick to variadic function, another option would be to not introduce ip1 and ip2 inside the function, but simply use ip[0] and ip[1]. And to avoid runtime panic if less than 2 arguments is passed, you may append an empty string yourself, e.g.:

func myvariadic(ip ...string) {
    if len(ip) < 2 {
        ip = append(ip, "")
    }
    fmt.Println(ip[0], ip[1])
}

And the version that also deals with 0 arguments:

func myvariadic(ip ...string) {
    for len(ip) < 2 {
        ip = append(ip, "")
    }
    fmt.Println(ip[0], ip[1])
}

This latter version makes sure the ip variable (of slice type) will have at least 2 elements, even if 0 is passed.

icza
  • 389,944
  • 63
  • 907
  • 827
2

Declare all locals up front and remove else. This is the only other way I could think of:

func myvariadic(ip ...string) {
    ip1 := ip[0]
    var ip2 string
    if len(ip) > 1 { 
        ip2 = ip[1] 
    }

    fmt.Println(ip1,ip2)
manikawnth
  • 2,739
  • 1
  • 25
  • 39
1

You don't need to initialize at all. All primitive types are initialized to their default values in Go.

IOW, this is true.

a := ""
var b string
fmt.Println(a == b)

https://play.golang.org/p/hwQmU4Myrp

Therefore, you inferred assignment of ip2 := "" is already the most succinct version you can type.

eduncan911
  • 17,165
  • 13
  • 68
  • 104
  • But the problem is that I will get 'out of index' in myvariadic func in case of more than 1 argument because ip[1] will not exists – irom Jun 10 '17 at 13:11