Skip to content

Instantly share code, notes, and snippets.

@Petelin
Last active November 3, 2019 01:39
Show Gist options
  • Save Petelin/a7bf8ccfd657536d46aaa355c6dc421a to your computer and use it in GitHub Desktop.
Save Petelin/a7bf8ccfd657536d46aaa355c6dc421a to your computer and use it in GitHub Desktop.
递归函数加装饰器
package main
import "fmt"
type FibI interface {
Fib(n int) int
Wrap(fib FibI) FibI
}
type Fib struct {
Wrapper FibI
}
func (this *Fib) Fib(n int) int {
wrapper := this.Wrapper
if this.Wrapper == nil {
wrapper = this
}
if n == 0 {
return 0
}
if n == 1 {
return 1
}
// call son
return wrapper.Fib(n-1) + wrapper.Fib(n-2)
}
func (this *Fib) Wrap(fib FibI) FibI {
this.Wrapper = fib
return this
}
type CacheFib struct {
Wrapper FibI
cache map[int]int
}
func (this *CacheFib) Wrap(fib FibI) FibI {
this.Wrapper = fib
return this
}
func (this *CacheFib) Fib(n int) int {
if this.cache == nil {
this.cache = make(map[int]int)
}
if ans, ok := this.cache[n]; ok {
return ans
}
ans := this.Wrapper.Fib(n)
this.cache[n] = ans
return ans
}
type CounterFib struct {
Wrapper FibI
Counter int
}
func (this *CounterFib) Wrap(fib FibI) FibI {
this.Wrapper = fib
return this
}
func (this *CounterFib) Fib(n int) int {
this.Counter++
return this.Wrapper.Fib(n)
}
func main() {
fib := new(Fib)
fmt.Println("result fib", fib.Fib(10))
cacheFib := new(CacheFib)
counterFib := new(CounterFib)
counterCacheFib := cacheFib.Wrap(counterFib.Wrap(fib.Wrap(cacheFib)))
fmt.Println("result cache:counter:fib", counterCacheFib.Fib(10))
fmt.Printf("count: %d, cache: %v", counterFib.Counter, cacheFib.cache)
}
@Petelin
Copy link
Author

Petelin commented Nov 2, 2019

use globe variable

// use function program 
package main

import "fmt"

type FibI func(int) int

var Fib FibI

func init() {
	// use default one
	Fib = BaseFib()
}

func BaseFib() FibI {
	return func(n int) int {
		if n == 0 {
			return 0
		}
		if n == 1 {
			return 1
		}
		return Fib(n-1) + Fib(n-2)
	}
}

func CounterFib(counter *int, f FibI) FibI {
	return func(n int) int {
		*counter++
		return f(n)
	}
}

func CacheFib(cache map[int]int, f FibI) FibI {
	return func(n int) int {
		if ans, ok := cache[n]; ok {
			return ans
		}
		ans := f(n)
		cache[n] = ans
		return ans
	}
}

func main() {
	var counter int
	var cache = make(map[int]int)
	// change it to another one
	// however we cannot creat two different Fib function
	Fib = CacheFib(cache, CounterFib(&counter, BaseFib()))
	fmt.Println(Fib(10), counter, cache)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment