How can i create a counter decorator in go?

113 views
Skip to first unread message

林风

unread,
Nov 2, 2019, 2:20:02 AM11/2/19
to golang-nuts
let's say i have a function or method to get fib

func fib(n int){
 
...
 
return fib(n-1) + fib(n-2)
}


now i want to add a counter to track how many times i have called to fib
.

in python or jave i can easy use `decorator patten` to do it.

but
in go, you can not change fib since it is a function. if you define fib as a method, you cannot do it either since go did not have `Inherited`. you cannot call father class.

so golang did
not support such thing? can we just reflect to do so?  






burak serdar

unread,
Nov 2, 2019, 2:30:33 AM11/2/19
to 林风, golang-nuts
There is no built-in way to do that. I don't think you can do that
with reflect either. However, if you need such decorators, you can use
an interface or a function pointer:

type fib interface {
fib(int) int
}

func f(in fib) {
in.fib(...)
}

You can pass in an implementation of fib that will do whatever you want.

With a function pointer:

func f(fib func(int) int) {
fib(...)
}

And if you need to count how many times f calls fib:

...
count:=0
f(func(in int) int {
count++
return originalFib(in)
}
}



>
>
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/84685fb5-8657-4f57-94f1-4b444d722976%40googlegroups.com.
Message has been deleted

林风

unread,
Nov 2, 2019, 4:47:23 AM11/2/19
to golang-nuts
Hi, thanks for your answer, and i really cannot understander your code. can you write a more clear version in go play ground? 
i already create a template. pls notice that we cannot change origin fib function.

在 2019年11月2日星期六 UTC+8下午2:30:33,burak serdar写道:
> To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

林风

unread,
Nov 2, 2019, 4:50:22 AM11/2/19
to golang-nuts
you may say i can write a fib2 which have fib1+counter. but that is really bad way to write code. and that's why we need decorator. 


在 2019年11月2日星期六 UTC+8下午2:30:33,burak serdar写道:
On Sat, Nov 2, 2019 at 12:20 AM 林风 <petel...@gmail.com> wrote:
> To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

林风

unread,
Nov 2, 2019, 6:32:55 AM11/2/19
to golang-nuts
there is a way i can do the base, but we still change old function due limit on go



在 2019年11月2日星期六 UTC+8下午4:50:22,林风写道:

Tamás Gulácsi

unread,
Nov 2, 2019, 7:44:02 AM11/2/19
to golang-nuts
You CAN override the function, but only if it is overridable (exported and changeable):

```
var Fib func(n int)
func init(){

 
Fib = func(n int) {
    ...

   
return Fib(n-1) + Fib(n-2)
  }
}
```
this way you can override it:
```
ori := pkg.Fib
pkg.Fib = func(n int) {
  count++
  ori(n)
}
```

burak serdar

unread,
Nov 2, 2019, 11:27:15 AM11/2/19
to 林风, golang-nuts
You don't need to change the original function. Below, Fib(int) int is
the original function, and it illustrates two ways to decorate it.

https://play.golang.org/p/K6us_rHIsyM

Neither is a *bad* way to write code. Go is a different language so
some things you're used to in other languages must be done in
different ways. This sometimes requires you to re-engineer your
solution. So trying to replicate a Java decorator pattern
implementation in Go using Java features won't work. Change the way
you're trying to solve your problem.

You use decorators to make existing code fit another scenario. For
this to work, the receiving end of the problem must be able to handle
such decoration as well. If you have code that uses the function `Fib`
directly, then you cannot override Fib. You cannot override Fib in
Java either (don't know about python). Your code should be able to get
an indirection of Fib (either an interface or a function pointer) so
you can override it.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ad4658a5-c6a6-4cfb-ad48-95ce8ecbfa2b%40googlegroups.com.

林风

unread,
Nov 2, 2019, 12:09:55 PM11/2/19
to golang-nuts
totally agree with not use old java thing in go. but here we are trying to solve a real problem. 
i read your code, it make sense to me we need a interface to fib, so i write such code (still i don't think your code can work with fib(n) n>1 since you did not use Recursive, when you use Recursive in fib or anywhere you will know why it is hard to implement such thing) 


i think we can over this discussion. the solution above is enough to me to solve related problem. 

Thanks again to inspire me~

在 2019年11月2日星期六 UTC+8下午11:27:15,burak serdar写道:

林风

unread,
Nov 2, 2019, 12:23:22 PM11/2/19
to golang-nuts
thanks for the idea, totally works. simple than my interface implement. 

@burak serdar not sure you are talking about this kind of program or not, if yes, then sorry for my misunderstanding. it works. 

https://play.golang.org/p/DnSc5vgItsL

在 2019年11月2日星期六 UTC+8下午7:44:02,Tamás Gulácsi写道:
Reply all
Reply to author
Forward
0 new messages