首页 > 解决方案 > 创建动态函数

问题描述

我需要在 Golang 中实现一个现有的逻辑。一般来说,它是这样的:

// Function receives an object with a variable type (struct)
func(dynObject interface{}) {

    var variableFunc ... // What should be here?

    // Some things to do depending on the input param type
    switch dynObject.(type) {
    case *objA:
        // do some job
    case *objB:
        // do some job
    }

    // ...
    // Creating and calculating some variables for the following loop
    // ...

    humans := []*Humans{ ....... }
    sum := []int{}

    for _, human := range humans {
        result := variableFunc(dynObject, human)
        sum = append(sum, result)
    }
}

如您所见 - 作为输入,有一个dynObject,它是一个结构,但可以是任何一些预定义的结构。后面有一个函数variableFunc必须取这个对象和进程,处理逻辑也取决于类型。所以类型objA需要与objB不同的逻辑。

我不知道实现这一点的正常方法。如何创建这个动态函数,它可以将不同的结构作为输入并对其应用所需的逻辑?目前我收到一个错误,该函数需要另一种类型作为输入。我希望避免额外的开关盒,因为已经存在一个。

当然,我尝试创建一个预定义的函数,并使用接口,然后以某种方式在现有的 switch-case 中重新定义它,但没有运气。我需要你的帮助

标签: go

解决方案


package main

import "fmt"

func main() {
    common(4)
    common("whitespace")
}
func common(a interface{}) {
    switch a.(type) {
    case int:
        div(a.(int), 2)
        break
    case string:
        sayHello(a.(string))
        break
    default:
        //nothing
    }
    return
}
func div(a, b int) {
    fmt.Printf("%d", a/b)
    return
}
func sayHello(a string) {
    fmt.Printf("%s", a)
}

mainfunction 调用一个common函数,这又调用了两个不同的函数,它们具有不同的函数签名。您可以看到他们执行不同的操作。所以这将为不同的输入打印不同的结果。如果在你的 switch 语句中调用不同的函数是你想要做的(我可以从你的评论中收集到),那么应该这样做。让我知道。


在我的 switch-case 里面有一项工作要做,然后它的结果被用来计算其他变量(在我的例子中是中间部分),然后我才调用 variableFunc()

package stackoverflow

import "fmt"

func common(a interface{}) {
    switch a.(type) {
    case int:
        defer func(b int) {
            fmt.Printf("%d \n", b/2)
        }(a.(int))
        break
    case string:
        defer func(b string) {
            fmt.Printf("hello %s \n", b)
        }(a.(string))
        break
    default:
        //nothing
    }

    //do something here
    fmt.Println("did something here test")
    // the function gets called after
    return
}

你可以使用延迟。因此,这不是 defer 的常规用法。但从技术上讲,它可以用于这样的事情。上述功能只有在//something完成后才会执行,我相信这就是您所追求的那种灵活性。如果某些函数出现恐慌,则该语句将在执行和退出之间出现。所以,你必须知道你在做什么。


或者你可以使用它,以防你有参数在稍后阶段进入。

package stackoverflow

import "fmt"

func common(a interface{}) {
    var f func(interface{}, int)
    switch a.(type) {
    case int:
        f = func(s interface{}, b int) {
            fmt.Printf("%d and %d\n", s.(int)/2, b)
        }
        break
    case string:
        f = func(b interface{}, c int) {
            fmt.Printf("hello %s and %d \n", b.(string), c)
        }
        break
    default:
        //nothing
    }
    //do something here
    fmt.Println("did something here test")
    // the function gets called after
    var x int = 21

    f(a, x)

    return
}

推荐阅读