Golang : Function wrapper that takes arguments and return result example




Continuing from our previous "primitive" tutorial on implementing a simple metaprogramming by creating a wrapper for a function. In this tutorial, we will explore how to define a wrapper function that takes in arguments and how to return a result.

This code example shows how to write a wrapper function the takes in an argument and influence the log level output.

 package main

 import (
 "fmt"
 "github.com/sirupsen/logrus"
 "time"
 )

 var log = logrus.New()

 type toBeWrapped func()

 func LogTimeTaken(function toBeWrapped, level int) {

 // 0 for debug, 1 for Info, 2 for Warn, 3 for Error, 4 for Fatal, 5 for Panic

 if level == 0 {
 log.Level = logrus.DebugLevel
 } else if level == 1 {
 log.Level = logrus.InfoLevel
 } else if level == 2 {
 log.Level = logrus.WarnLevel
 } else if level == 3 {
 log.Level = logrus.ErrorLevel
 } else if level == 4 {
 log.Level = logrus.FatalLevel
 } else if level == 5 {
 log.Level = logrus.PanicLevel
 }

 startTime := time.Now()
 function()
 endTime := time.Now()

 log.Info("Time taken is about ----->> ", endTime.Sub(startTime))
 log.Warn("TOO SLOW!")

 if level >= 3 {
 log.Error("No INFO and WARNING this time. Log level is set to Error. Abort!")
 }
 }

 func main() {

 HWfunc := func() {
 fmt.Println("\n\n\nHello World \n\n\n")
 }

 // set to debug level, will not abort, will display both INFO and WARNING
 LogTimeTaken(HWfunc, 0)

 // set to warning level, STILL WILL not abort.
 // will not display INFO because WARN level is higher than INFO

 LogTimeTaken(HWfunc, 2)


 // set to ErrorLevel
 LogTimeTaken(HWfunc, 3)

 }

Output:

Hello World

INFO[0000] Time taken is about ----->> 32.551µs

WARN[0000] TOO SLOW!

Hello World

WARN[0000] TOO SLOW!

Hello World

ERRO[0000] No INFO and WARNING this time. Log level is set to Error. Abort!

As you can see, the output behavior is controlled by the log level that we set in the second argument of the LogTimeTaken() function.

And now let's learn how to return a string value from the wrapped function, we simply change the type from

 type toBeWrapped func()

to

 type toBeWrapped func() string

We will use string type for this tutorial, you are welcome to change to int or any type you prefer. Run this code below to see how a wrapped function can return a string value.

 package main

 import (
 "fmt"
 )

 // we expect the wrapped function to return string type
 // change to suitable type for your own use or use interface for returning dynamic value

 type toBeWrapped func() string

 func WrappedFunctionThatReturnSomething(function toBeWrapped) string { // added string type for return
 response := function() // wrapped function return value will be stored in response variable
 return response // and return to outer function - the wrapper function
 }

 func main() {

 WrappedFunction := func() string { // added string type for return
 return "Hello World from a wrapped(inner) function"
 }

 returned := WrappedFunctionThatReturnSomething(WrappedFunction)
 fmt.Println("The wrapped function says : ", returned)

 }

Output:

The wrapped function says : Hello World from a wrapped(inner) function

Happy coding!

References:

https://socketloop.com/tutorials/golang-metaprogramming-example-of-wrapping-a-function

  See also : Golang : How to save log messages to file?





By Adam Ng

IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.


Advertisement