8、go 实现一个cache 缓存

46 阅读1分钟

泛型方式

package g_cache

import "sync"

type Cache[K comparable, V any] interface {
    Get(key K) interface{}
    Set(key K, value interface{})
    Delete(key K)
    GetValue(key K) (isExist bool, val V)
}

type mapCache[K comparable, V any] struct {
    data map[K]interface{}
    lock sync.RWMutex
}

func NewMapCache[K comparable, V any]() Cache[K, V] {
    return &mapCache[K, V]{
        data: make(map[K]interface{}),
    }
}

func (m *mapCache[K, V]) Get(key K) interface{} {
    m.lock.RLock()
    defer m.lock.RUnlock()
    return m.data[key]
}

func (m *mapCache[K, V]) GetValue(key K) (isExist bool, val V) {
    m.lock.RLock()
    defer m.lock.RUnlock()
    val, isExist = m.data[key].(V)
    return
}

func (m *mapCache[K, V]) Set(key K, value interface{}) {
    m.lock.Lock()
    defer m.lock.Unlock()
    m.data[key] = value
}

func (m *mapCache[K, V]) Delete(key K) {
    m.lock.Lock()
    defer m.lock.Unlock()
    delete(m.data, key)
}

固定类型方式

package g_cache

import "sync"

type CacheString interface {
    Get(key string) interface{}
    Set(key string, value interface{})
    Delete(key string)
    GetValueString(key string) (isExist bool, val string)
}

type mapCacheString struct {
    data map[string]interface{}
    lock sync.RWMutex
}

func NewMapCacheString() CacheString {
    return &mapCacheString{
       data: make(map[string]interface{}),
    }
}

func (m *mapCacheString) Get(key string) interface{} {
    m.lock.RLock()
    defer m.lock.RUnlock()
    return m.data[key]
}

func (m *mapCacheString) GetValueString(key string) (isExist bool, val string) {
    m.lock.RLock()
    defer m.lock.RUnlock()
    val, isExist = m.data[key].(string)
    return
}

func (m *mapCacheString) Set(key string, value interface{}) {
    m.lock.Lock()
    defer m.lock.Unlock()
    m.data[key] = value
}

func (m *mapCacheString) Delete(key string) {
    m.lock.Lock()
    defer m.lock.Unlock()
    delete(m.data, key)
}

测试运行

package g_cache

import (
    "fmt"
    "testing"
)

func TestCacheString(t *testing.T) {
    fmt.Println("---------------------string---------------------------")

    cacheString := NewMapCacheString()
    cacheString.Set("1", "1")
    fmt.Println(cacheString.GetValueString("1")) // true 1
    fmt.Println(cacheString.Get("1"))            // 1
    cacheString.Delete("1")
    fmt.Println(cacheString.GetValueString("1")) // false ""
    fmt.Println(cacheString.Get("1"))            // nil

    fmt.Println("----------------------int--------------------------")

    cacheInt := NewMapCacheInt()
    cacheInt.Set(1, 1)
    fmt.Println(cacheInt.GetValueInt(1)) // true 1
    fmt.Println(cacheInt.Get(1))         // 1
    cacheInt.Delete(1)
    fmt.Println(cacheInt.GetValueInt(1)) // false 0
    fmt.Println(cacheInt.Get(1))         // n0

    fmt.Println("----------------------T string--------------------------")

    cacheT := NewMapCache[string, string]()
    cacheT.Set("1", "1")
    fmt.Println(cacheT.GetValue("1")) // true 1
    fmt.Println(cacheT.Get("1"))      // 1
    cacheT.Delete("1")
    fmt.Println(cacheT.GetValue("1")) // false ""
    fmt.Println(cacheT.Get("1"))      // nil

    fmt.Println("----------------------T int--------------------------")
    cacheTInt := NewMapCache[int, int]()
    cacheTInt.Set(1, 1)
    fmt.Println(cacheTInt.GetValue(1)) // true 1
    fmt.Println(cacheTInt.Get(1))      // 1
    cacheTInt.Delete(1)
    fmt.Println(cacheTInt.GetValue(1)) // false ""
    fmt.Println(cacheTInt.Get(1))      // nil
}