3 回答

TA貢獻(xiàn)1859條經(jīng)驗(yàn) 獲得超6個(gè)贊
您可以使用閉包;并讓閉包管理緩存。
func InitExpensiveFuncWithCache() func(p int) int {
var cache = make(map[int]int)
return func(p int) int {
if ret, ok := cache[p]; ok {
fmt.Println("from cache")
return ret
}
// expensive computation
time.Sleep(1 * time.Second)
r := p * 2
cache[p] = r
return r
}
}
func main() {
ExpensiveFuncWithCache := InitExpensiveFuncWithCache()
fmt.Println(ExpensiveFuncWithCache(2))
fmt.Println(ExpensiveFuncWithCache(2))
}
output:
4
from cache
4
veryExpensiveFunctionCached := InitExpensiveFuncWithCache()
并將包裝的函數(shù)與代碼一起使用。你可以在這里試試。
如果希望它是可重用的,請(qǐng)將簽名更改為接受函數(shù)作為參數(shù)。將其包裝在閉包中,用它替換昂貴的計(jì)算部分。InitExpensiveFuncWithCache(func(int) int)

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊
如果要在 http 處理程序中使用此緩存,則需要小心同步。在 Go 標(biāo)準(zhǔn) lib 中,每個(gè) http 請(qǐng)求都在專用的 goroutine 中處理,此時(shí)我們處于并發(fā)和爭(zhēng)用條件的領(lǐng)域。我建議使用RWMutex來確保數(shù)據(jù)一致性。
至于緩存注入,您可以在創(chuàng)建http處理程序的函數(shù)中注入它。這是一個(gè)原型
type Cache struct {
store map[int]int
mux sync.RWMutex
}
func NewCache() *Cache {
return &Cache{make(map[int]int), sync.RWMutex{}}
}
func (c *Cache) Set(id, value int) {
c.mux.Lock()
c.store[id] = id
c.mux.Unlock()
}
func (c *Cache) Get(id int) (int, error) {
c.mux.RLock()
v, ok := c.store[id]
c.mux.RUnlock()
if !ok {
return -1, errors.New("a value with given key not found")
}
return v, nil
}
func handleComplexOperation(c *Cache) http.HandlerFunc {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request){
})
}

TA貢獻(xiàn)1802條經(jīng)驗(yàn) 獲得超6個(gè)贊
Go 標(biāo)準(zhǔn)庫使用以下樣式來提供“靜態(tài)”函數(shù)(例如,標(biāo)志。命令行),但利用基礎(chǔ)狀態(tài):
// "static" function is just a wrapper
func Lookup(p int) int { return expCache.Lookup(p) }
var expCache = NewCache()
func newCache() *CacheExpensive { return &CacheExpensive{cache: make(map[int]int)} }
type CacheExpensive struct {
l sync.RWMutex // lock for concurrent access
cache map[int]int
}
func (c *CacheExpensive) Lookup(p int) int { /*...*/ }
這種設(shè)計(jì)模式不僅允許簡(jiǎn)單的一次性使用,而且還允許隔離使用:
var (
userX = NewCache()
userY = NewCache()
)
userX.Lookup(12)
userY.Lookup(42)
- 3 回答
- 0 關(guān)注
- 135 瀏覽
添加回答
舉報(bào)