【问题标题】:Can golang take a function with unknown number of parameters as an argument to another functiongolang可以将参数数量未知的函数作为另一个函数的参数吗
【发布时间】:2015-12-02 17:12:59
【问题描述】:

假设我有一个像下面这样的程序

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) 行进行哪些修改才能使其正常工作?

PS:请尝试给出一个通用的答案,而不是针对我提到的确切场景提供解决方法

编辑:- 这不是 this 问题的重复。 我不是在寻找扩展的论点。我会有不同类型的参数和不同数量的参数

编辑:- 我会更清楚地解释我的场景。

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

例如:-

向“某人”说“问候”

以及相关的功能

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

另一行说

添加 、 和

及相关功能

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

我有一种机制可以扫描所有功能并将其添加到地图中,并带有相关的场景。我的程序知道要执行哪个函数、它的参数数量和参数。

我的问题是,如何使地图通用,以便我可以使用不同数量/类型的参数存储不同的函数。

【问题讨论】:

  • 您有reflectioninterface 标签,但是这两个主题都不在您的问题中。 “通用”答案是使用可变参数函数。你能解释一下为什么你不想使用可变参数函数吗? func Three 无效,所以我不确定你想通过混合类型来完成什么。
  • @JimB 假设我的函数三是 func Three(n1 string,n2 bool,n3 int) { fmt.Println("Foo = ",n1, n2, n3) } 在这种情况下我可以不使用可变参数对吗?
  • 你这里有一个人为的例子,这没有任何意义。您出于某种原因与类型系统作斗争,但我不确定为什么。你只想要type Executable func(...interface{})吗?
  • 正如@JimB 提到的,我认为您想使用interface{} 类型。这允许具有不同类型的不同数量的参数。或者根据您真正想要实现的目标,您也可以使用...CustomInterface{} 并定义对您的功能有用的自己的界面。

标签: reflection go interface


【解决方案1】:
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)
    }
}

我完全不知道你想在这里实现什么。您可以采用未知数量的未知类型的参数。但你不应该。您可以并且应该做的是采用未知数量的参数,这些参数满足您编写的自定义接口并将在您的函数中使用,否则它没有意义并且会在某一时刻强制您使用反射来了解参数的类型。

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

【讨论】:

    【解决方案2】:

    “所提到的确切场景”的答案是:

    不能 这样做 这个。

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

    【讨论】:

    • 我刚看了 rob pike 的视频,youtube.com/watch?v=PAAkCSZUG1c他问人们不要使用反射...
    • 正如@Depado 的回答清楚地表明,你可以做到。也许你只是想说“语言的类型系统不是为此而设计的,所以你不应该这样做”。
    • @StefanoMozart 不,我想说“不,你不能”。 Depadas 的答案是一般问题的一个有限实例,因为 f(a ...X) 是一个具有 []X 类型参数的函数。
    猜你喜欢
    • 2020-01-19
    • 2013-04-23
    • 2013-03-20
    • 1970-01-01
    • 2022-01-11
    • 2017-08-07
    • 2018-11-13
    • 1970-01-01
    相关资源
    最近更新 更多