douliedai4838 2018-09-04 18:17
浏览 8

创建动态功能

There is an existing logic I need to achieve in Golang. In general it is something like:

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

As you see - as an input there is a dynObject which is a struct, but can be any of some predefined structs. Later there is a function variableFunc which must take this object and process, and processing logic also depends on the type. So type objA requires different logic than objB.

I don't know a normal way to implement this. How do I create this dynamic function, which can take different structs as input and apply needed logic to it? At the moment I get an error, that function expects another type as an input. And I wish to avoid additional switch-case, because one already exists.

Of course I tried to create a predefined func., and with interfaces, then somehow redefine it inside of existing switch-case, but no luck. I need your help

  • 写回答

1条回答 默认 最新

  • dqd22496 2018-09-05 03:37
    关注
    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)
    }
    

    main function calls a common function, this in turn calls two different functions, which have different function signatures. You can see that they perform different actions. So this will print different results for different inputs. If calling different functions inside your switch statement is what you, wanted to do(as much I can glean from your comments), then this should do it. Let me know.


    there is a job to do inside my switch-case, then it's result is being used to calculate other variables (middle section in my example), and only after that I call variableFunc()

    package stackoverflow
    
    import "fmt"
    
    func common(a interface{}) {
        switch a.(type) {
        case int:
            defer func(b int) {
                fmt.Printf("%d 
    ", b/2)
            }(a.(int))
            break
        case string:
            defer func(b string) {
                fmt.Printf("hello %s 
    ", b)
            }(a.(string))
            break
        default:
            //nothing
        }
    
        //do something here
        fmt.Println("did something here test")
        // the function gets called after
        return
    }
    

    you can use defer. So, this isn't a conventional use of defer. But technically it can be used for something like this. The above functionality will execute only after //something gets done, which I believe is the kind of flexibility you are after. If some function panics, this statement will come in between execution and exiting. So, you have to know what you are doing.


    Or you can use this, in case you have parameters coming in at a later stage.

    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
    ", s.(int)/2, b)
            }
            break
        case string:
            f = func(b interface{}, c int) {
                fmt.Printf("hello %s and %d 
    ", 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
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思