Return only the first result of a multiple return values in golang

Viewed 16192

Absolute newbie question here.

Some functions in Go return more than one value (normally, the value and an error). I was writing a func who return the return value of one of those functions, and even if it is very easy to put the values on variables and return only the first one, I have the doubt if I could do the same in only one line without the extra variable. This is something often uses in other languages like C, Java, C#, Ruby, etc

func someFunc (param string) int {
   // do something with the string, not very important
   return strconv.Atoi(param) 
}

I know this works

func someFunc (param string) int {
   // do something with the string, not very important
   var result int
   result, _ = strconv.Atoi(param)
   return result 
}

It is this possible in Go? It is considered a "good practice" (like in Java*)

Note: Before someone say that this technique is not a good practice in Java, clarify that is not important for the question, but some people (like the ones in the company I work) encourage that style.

2 Answers

Use a short variable declaration for the shortest code to accomplish this goal:

func SomeFunc(parm string) int {
    result, _ := strconv.Atoi(param)
    return result
}

There is no one line solution without introducing a helper function that accepts two arguments and returns the first. One of these helper functions would be needed for each combination of types where you want to ignore a value.

Your best possible one-liner is a helper function written as:

func first(n int, _ error) int {
    return n
}

func SomeFunc(param string) int {
    return first(strconv.Atoi(param))
}

Note that:

  • the argument types and positions must match exactly
  • the second argument to first has the blank identifier (_), making it clear that you wish to completely ignore it. [1]

If you absolutely don't want to declare a named function, you may use a function literal, but that looks real ugly:

func SomeFunc(param string) int {
    return func(n int, _ error) int { return n }(strconv.Atoi(param))
}

In general, the helper function is worth it if you have a lot of repetition in your code. Otherwise just use a temp variable, which looks clean and idiomatic:

func SomeFunc(param string) int {
    n, _ := strconv.Atoi(param)
    return n
}

Playground: https://play.golang.org/p/X8EOh_JVDDG


Once generics will be added to the language in Go 1.18, you will be able to write a helper function that can be used with any return pair and preserve type safety on the first one:

func first[T, U any](val T, _ U) T {
    return val
}

func SomeFunc(param string) int {
    return first(strconv.Atoi(param))
}

Go2 Playground: https://go2goplay.golang.org/p/vLmTuwzrl5o


Footnotes:

[1] Keep in mind that in case of strings.Atoi the second return value is an error, and ignoring errors is bad practice. However there are cases where the success of the operation truly doesn't matter, then it's fine to use _ to ignore the argument.

Related