Go语言可以将具有未知数量参数的函数作为参数传递给另一个函数。

huangapple go评论78阅读模式
英文:

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

问题

假设我有一个如下所示的程序:

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)
}

我想将Execute函数作为一个通用函数,可以接收具有不同类型和数量参数的函数,Executable的类型应该是什么?

换句话说,如果我取消上面程序中的注释,它将会出错。我应该如何修改type Executable func(int)这一行使其正常工作?

注意:请尽量给出一个通用的答案,而不是针对我提到的具体情况的解决方法

编辑:这不是这个问题的重复。
我不是在寻找扩展参数。我将有不同类型和不同数量的参数

编辑:我将更清楚地解释我的情况。

我有一个BDD风格的测试执行器,它解析一行文本并执行与之关联的函数,并传递适当的参数。

例如:

对“某人”说“问候”

和相关的函数

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

另一行说

将<2>、<3>和<4>相加

和相关的函数

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

我有一种机制来扫描所有的函数并将其添加到一个映射中,与相关的场景关联起来。我的程序知道要执行哪个函数,它需要多少个参数以及这些参数是什么。

我的问题是,如何使映射成为通用的,以便我可以存储具有不同数量/类型参数的不同函数。

英文:

Suppose I have a program like below

package main

import &quot;fmt&quot;

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(&quot;1&quot;,2,3)
	}
}
func One(n int) {
	fmt.Println(&quot;Foo = &quot;,n)
}
func Two(n1,n2 int) {
	fmt.Println(&quot;Foo = &quot;,n1+n2)
}
func Three(n1 string,n2,n3 int) {
	fmt.Println(&quot;Foo = &quot;,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, &quot;, &quot;, 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(&quot;Sum is : &quot;, 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.

答案1

得分: 3

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)
	}
}

我不太清楚你在这里想要实现什么。你可以使用未知类型的未知数量的参数。但是你不应该这样做。你可以和应该做的是接受一个未知数量的参数,这些参数满足你编写的自定义接口,并且在函数内部使用它们,否则这没有意义,并且在某个时候会迫使你使用反射来知道参数的类型。

如果你试图避免使用类型,那么使用强类型语言就没有意义。

英文:

<!-- language: go -->

package main

import &quot;fmt&quot;

func Simple(args ...interface{}) {
	fmt.Println(&quot;Foo =&quot;, 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(&quot;1&quot;, 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.

答案2

得分: 2

“the exact scenario mentioned”的答案是:

不,你不能这样做。

(尤其是因为你不应该这样做。)

英文:

The answer to "the exact scenario mentioned" is:

No you cannot do this.

(Especially as you shouldn't.)

huangapple
  • 本文由 发表于 2015年12月3日 01:12:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/34048861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定