Manu Viswam
Manu Viswam

Reputation: 1646

Can golang take a function with unknown number of parameters as an argument to another function

Suppose I have a program like below

package main

import "fmt"

func main() {
    Execute(1,One)
//  Execute(2,Two)
//  Execute(3,Three)
}

type Executable func(int)

func Execute(noOfArgs int, fn Executable){
    switch noOfArgs {
        case 1 : fn(1)
//      case 2 : fn(1,2)
//      case 3 : fn("1",2,3)
    }
}
func One(n int) {
    fmt.Println("Foo = ",n)
}
func Two(n1,n2 int) {
    fmt.Println("Foo = ",n1+n2)
}
func Three(n1 string,n2,n3 int) {
    fmt.Println("Foo = ",n1+n2+n3)
}

And I would like to make the Execute function as a generic one which can receive functions with different number of arguments of different types, what should be the type of Executable ?

In other words, If I uncomment the commented lines in the above program, it will break. What modification should I make to the line type Executable func(int) to make it working?

PS : Please try to give a generic answer instead of giving a workaround for the exact scenario which I mentioned

EDIT:- This is not a duplicate of this question. I am not looking for expanding arguments. I will have different types of arguments and different number of arguments

EDIT:- I will explain my scenario more clearly.

I have a BDD style test executor which parses a line of text and execute the function associated with it, with appropriate arguments.

Eg :-

Say "greeting" to "someone"

and an associated function

func SayGreeting(greeting, person string) {
    fmt.Println(greeting, ", ", person)
}

another line which says

Add <2> , <3> and <4>

and associated function

func AddNum(n1, n2, n3 int) {
    sum := n1 + n2 + n3
    fmt.Println("Sum is : ", sum)
}

I have a mechanism to scan all the functions and add it to a map, with associated scenario. My program knows which function to execute, number of arguments to it and the arguments.

My problem is, how do I make the map generic so that I can store different functions with different number/type of arguments.

Upvotes: 1

Views: 6055

Answers (2)

Depado
Depado

Reputation: 4929

package main

import "fmt"

func Simple(args ...interface{}) {
    fmt.Println("Foo =", fmt.Sprint(args...))
}

func main() {
    Execute(1, Simple)
    Execute(2, Simple)
    Execute(3, Simple)
}

type Executable func(...interface{})

func Execute(noOfArgs int, fn Executable) {
    switch noOfArgs {
    case 1:
        fn(1)
    case 2:
        fn(1, 2)
    case 3:
        fn("1", 2, 3)
    }
}

I quite don't know what you're trying to achieve here. You can take an unknown number of arguments with unknown types. But you shouldn't. What you can and should do is take an unknown number of arguments that are satisfying a custom interface you wrote and that will be used inside your function, otherwise it doesn't make sense and will, at one point force you to use reflection to know the type of an argument.

There is no point in using a strongly typed language if you try to avoid the types.

Upvotes: 3

Volker
Volker

Reputation: 42468

The answer to "the exact scenario mentioned" is:

No you cannot do this.

(Especially as you shouldn't.)

Upvotes: 2

Related Questions