50

I have a function which returns a string under certain circumstances, namely when the program runs in Linux or MacOS, otherwise the return value should be nil in order to omit some OS-specific checks further in code.

func test() (response string) {
    if runtime.GOOS != "linux" {  
        return nil
    } else {
        /* blablabla*/
    }
}

however when I try to compile this code I get an error:

test.go:10:3: cannot use nil as type string in return argument.

If I return just an empty string like return "", I cannot compare this return value with nil further in code.

So the question is how to return a correct nil string value?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
sotona
  • 1,731
  • 2
  • 24
  • 34
  • 1
    Possible duplicate of [How to return int or nil in golang?](https://stackoverflow.com/questions/46726832/how-to-return-int-or-nil-in-golang) – Jonathan Hall Sep 10 '18 at 12:18

3 Answers3

73

If you can't use "", return a pointer of type *string; or–since this is Go–you may declare multiple return values, such as: (response string, ok bool).

Using *string: return nil pointer when you don't have a "useful" string to return. When you do, assign it to a local variable, and return its address.

func test() (response *string) {
    if runtime.GOOS != "linux" {
        return nil
    } else {
        ret := "useful"
        return &ret
    }
}

Using multiple return values: when you have a useful string to return, return it with ok = true, e.g.:

return "useful", true

Otherwise:

return "", false

This is how it would look like:

func test() (response string, ok bool) {
    if runtime.GOOS != "linux" {
        return "", false
    } else {
        return "useful", true
    }
}

At the caller, first check the ok return value. If that's true, you may use the string value. Otherwise, consider it useless.

Also see related questions:

How do I represent an Optional String in Go?

Alternatives for obtaining and returning a pointer to string: How do I do a literal *int64 in Go?

icza
  • 389,944
  • 63
  • 907
  • 827
  • 1
    well, looks like returning string pointer instead of the string itself is the best way to avoid additional entities – sotona Sep 10 '18 at 10:33
  • 3
    @sotona Depends on how (and how often) you intend to use this function. Multi-return values are quite common in Go, and working with string pointers is more cumbersome. I'd go with multi-return values in most of the time. – icza Sep 10 '18 at 10:46
10

Go has built-in support for multiple return values:

This feature is used often in idiomatic Go, for example to return both result and error values from a function.

In your case it could be like this:

func test() (response string, err error) {
    if runtime.GOOS != "linux" {  
        return "", nil
    } else {
        /* blablabla*/
    }
}

And then:

response, err := test()
if err != nil { 
    // Error handling code
    return;
}

// Normal code 

If you want to ignore the error, simply use _:

response, _ := test()
// Normal code
Nic
  • 12,220
  • 20
  • 77
  • 105
1

Go allows multiple return types. So use this to your advantage and return an error or any other type. Check this out for more info: http://golangtutorials.blogspot.com/2011/06/return-values-from-go-functions.html?m=1

Mightee
  • 689
  • 7
  • 22