type Fn func(x, y int) int
func (fn Fn) Chain(f Fn) Fn {
return func(x, y int) int {
fmt.Println(fn(x, y))
return f(x, y)
}
}
func add(x, y int) int {
fmt.Printf("%d + %d = ", x, y)
return x + y
}
func minus(x, y int) int {
fmt.Printf("%d - %d = ", x, y)
return x - y
}
func mul(x, y int) int {
fmt.Printf("%d * %d = ", x, y)
return x * y
}
func divide(x, y int) int {
fmt.Printf("%d / %d = ", x, y)
return x / y
}
func main() {
var result = Fn(add).Chain(Fn(minus)).Chain(Fn(mul)).Chain(Fn(divide))(10, 5)
fmt.Println(result)
}
package main
import (
"fmt"
"reflect"
)
func Decorate(impl interface{}) interface{} {
fn := reflect.ValueOf(impl)
inner := func(in []reflect.Value) []reflect.Value {
f := reflect.ValueOf(impl)
fmt.Println("Stuff before")
// ...
ret := f.Call(in)
fmt.Println("Stuff after")
// ...
return ret
}
v := reflect.MakeFunc(fn.Type(), inner)
return v.Interface()
}
var Add = Decorate(
func (a, b int) int {
return a + b
},
).(func(a, b int) int)
func main() {
fmt.Println(Add(1, 2))
}