Golang pass nil as optional argument to a function?

时间:2015-09-14 15:54:54

标签: go

In golang, http.NewRequest has a specification like this:

func NewRequest(method, urlStr string, body io.Reader) (*Request, error)

However, I can pass nil as the body option if I don't want to pass the body to an io.Reader object, like this:

req, err := http.NewRequest("GET", "http://www.blahblah.org", nil)

How do I implement this functionality in my code? I have a function that I want to pass an optional string value so that it can page through API results however if I pass a nil to the string input I get this:

./snippets.go:32: cannot convert nil to type string

The parameters for my function look like this:

func getChallenges(after string) ([]challenge, string, error)

5 个答案:

答案 0 :(得分:9)

Go does not have "optional" arguments as a generally understood concept in other languages; nil is just the zero value for an interface (io.Reader in this case).

The equivalent zero value for a string is an empty string:

getChallenges("")

If you want to accept 0 or more of the same argument type, you use the variadic syntax:

func getChallenges(after ...string) ([]challenge, string, error)

答案 1 :(得分:6)

您可以修改函数以接收指针值,如下所示:

func getChallenges(after *string) ([]challenge, string, error)

然后你可以将nil作为参数传递给它。但是在解除引用之前不要忘记检查after函数内的nil值,否则你会得到一个nil指针异常:

func getChallenges(after *string) ([]challenge, string, error) {
    if after == nil {
        // No value specified
    } else {
        fmt.Printf("After: %s\n", *after) // Note pointer dereferencing with "*"
    }
    // ...
}

另一种选择:

只需使用两个功能:

func getChallenges(after string) {}

func getAllChallenges() {
    return getChallenges(/* some default value here */)
}

答案 2 :(得分:4)

you can use ellipse operator to send the optional parameters.. don't pass anything in optional parameter and check the length of parameter. it should solve your problem

func foo(params ...int) {
   fmt.Println(len(params))
}

func main() {
    foo()
    foo(1)
    foo(1,2,3)
}

答案 3 :(得分:0)

也许将其包裹在 struct 中?

type NilableString struct {
    value string;
}

答案 4 :(得分:-1)

You can use reflect. In fact io.Reader is a interface.

So you can define signature like func getChallenges(after interface{}) ([]challenge, string, error)

interface{} is a empty interface, that is interface for anything.

But I suggest you use syntax args... to pass slice , refer to fmt.Printf implementation for usage, because if you pass no string the slice len is 0 and this will avoid the reflect which I think too heavy for your function.