Caching
Introduction
gcache is a module providing unified cache management, offering developers a customizable and flexible cache adapter interface, with a default high-speed in-memory cache adapter implementation.
Usage:
import "github.com/gogf/gf/v2/os/gcache"
Interface Documentation:
https://pkg.go.dev/github.com/gogf/gf/v2/os/gcache
Brief Introduction:
-
gcacheprovides a default high-speed in-memory cache object, which can be operated by package methods or created using theNewmethod. When using cache functions via package methods, operations are on a globally providedgcache.Cacheobject, hence be cautious of global key name collisions in use. -
The key type used in
gcacheisinterface{}, notstring, meaning any variable type can be used as a key name. However, it is generally recommended to usestringor[]byteas key names and to unify the key name data type for maintenance purposes. -
The key-value type stored by
gcacheisinterface{}, meaning any data type can be stored. When data is retrieved, it is returned asinterface{}. If conversion to other types is needed,gcache‘sGet*methods can conveniently obtain common types. Note, if you are sure that in-memory cache is being used, you can directly use assertions for type conversion; otherwise, it is recommended to use the returned generic object’s corresponding method for type conversion. -
Additionally, note that the cache expiration time parameter
durationingcacheis of typetime.Duration. When setting a cache variable,duration = 0means no expiration,duration < 0means immediate expiration, andduration > 0means timeout expiration.
Notes
About Key Name Data Types
You may notice that the data types of key-value pairs in the cache component are interface{}. This design aims for generality and ease of use, but requires attention to interface{} comparison: true matching requires both data and type to be equal. Here‘s an example.
package main
import (
"fmt"
"github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
var (
ctx = gctx.New()
key1 int32 = 1
key2 float64 = 1
value = `value`
)
_ = gcache.Set(ctx, key1, value, 0)
fmt.Println(gcache.MustGet(ctx, key1).Val())
fmt.Println(gcache.MustGet(ctx, key2).Val())
}
After execution, the console outputs:
<nil>
As you can see, although key1 and key2 have the same value, their types are different, so key2 cannot be used to obtain the key-value pair.
About Retrieving Object Key-Values
Since the key-value type is also interface{}, it is often converted to the desired data type after retrieval. A common conversion method is direct type assertion, but this carries a risk. The gcache component uses an adapter interface design pattern , meaning the implementation (besides the default in-memory adapter) often changes the original data type (non-memory implementations often involve serialization/deserialization storage). Thus, direct type assertion for data type conversion is not recommended.
To improve key-value retrieval, the cache component does not directly return interface{} but a framework generic *gvar.Var object, allowing developers to convert to the needed data type based on business scenarios. This is particularly useful for object cache storage and reading scenarios. Here‘s an example:
package main
import (
"fmt"
"github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gctx"
)
func main() {
type User struct {
Id int
Name string
Site string
}
var (
ctx = gctx.New()
user *User
key = `UserKey`
value = &User{
Id: 1,
Name: "GoFrame",
Site: "https://goframe.org",
}
)
err := gcache.Set(ctx, key, value, 0)
if err != nil {
panic(err)
}
v, err := gcache.Get(ctx, key)
if err != nil {
panic(err)
}
if err = v.Scan(&user); err != nil {
panic(err)
}
fmt.Printf(`%#v`, user)
}
After execution, the console outputs:
&main.User{Id:1, Name:"GoFrame", Site:"https://goframe.org"}
