设计思路
- 接口定义:定义一个通用的缓存接口,包含
Set
、Get
和Delete
方法,这些方法将作为缓存操作的标准接口。
- 泛型实现:使用Go 1.18引入的泛型来支持多种数据类型的缓存。这样可以在编译时确保类型安全,同时减少重复代码。
- 并发安全:使用
sync.RWMutex
来保证缓存操作的并发安全性。读操作使用读锁,写操作使用写锁,以避免数据竞争。
- 性能优化:使用Go的map数据结构来存储缓存数据,因为map在查找、插入和删除操作上具有较好的性能。同时,合理使用锁机制,尽量减少锁的粒度,提高并发性能。
核心代码实现
package main
import (
"fmt"
"sync"
)
// 定义缓存接口
type CacheInterface[K comparable, V any] interface {
Set(key K, value V)
Get(key K) (V, bool)
Delete(key K)
}
// 缓存结构体
type Cache[K comparable, V any] struct {
data map[K]V
mu sync.RWMutex
}
// 创建新的缓存实例
func NewCache[K comparable, V any]() *Cache[K, V] {
return &Cache[K, V]{
data: make(map[K]V),
}
}
// 设置缓存项
func (c *Cache[K, V]) Set(key K, value V) {
c.mu.Lock()
defer c.mu.Unlock()
c.data[key] = value
}
// 获取缓存项
func (c *Cache[K, V]) Get(key K) (V, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
value, exists := c.data[key]
return value, exists
}
// 删除缓存项
func (c *Cache[K, V]) Delete(key K) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.data, key)
}
使用示例
func main() {
// 创建一个字符串到整数的缓存
cache := NewCache[string, int]()
// 设置缓存项
cache.Set("key1", 100)
// 获取缓存项
value, exists := cache.Get("key1")
if exists {
fmt.Printf("Value for key1: %d\n", value)
} else {
fmt.Println("Key not found")
}
// 删除缓存项
cache.Delete("key1")
// 再次获取缓存项
value, exists = cache.Get("key1")
if exists {
fmt.Printf("Value for key1: %d\n", value)
} else {
fmt.Println("Key not found")
}
}