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