Accept function in argument with empty interface return type

As the Go specification states:

A function type denotes the set of all functions with the same parameter and result types

In your case, your result types differ (string vs interface{})

To be able to receive a function with any kind of result type, test would have to be defined as:

func text(x interface{}) { ... }

and then you will have to use reflect package to call the function stored in x.

Edit

Such a test function would look like this:

func test(x interface{}) {
    v := reflect.ValueOf(x)

    if v.Kind() != reflect.Func {
        panic("Test requires a function")
    }

    t := v.Type()

    if t.NumIn() != 0 && t.NumOut() != 1 {
        panic("Function type must have no input parameters and a single return value")
    }

    values := v.Call(nil)

    val := values[0].Interface()
    // some more code..
}

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


You tripped over a very common misconception for Go newcomers: The empty interface interface{} does not mean "any type". Really, it does not. Go is statically typed. The empty interface interface {} is an actual (strongly typed type) like e.g. string or struct{Foo int} or interface{Explode() bool}.

That means if something has the type interface{} it has that type and not "any type".

Your function

func test(x func() interface{})

takes one parameter. This parameter is a (parameterless function) which returns a specific type, the type interface{}. You can pass any function to test which matches this signature: "No parameters and return interface{}". None of your functions a and b match this signature.

As said above: interface {} is not a magical abbreviation for "whatever",it is a distinct static type.

You have to change e.g. a to:

func a() interface{} {
    return "hello"
}

Now this might look strange as you return a string which is not of type interface{}. This works because any type is assignable to variables of type interface{} (as every type has at least no methods :-).

Tags:

Go