sync map的使用

754 阅读1分钟

使用

  • Store 写入
  • Load 读取,返回值有两个,第一个是value,第二个是bool变量表示key是否存在
  • Delete 删除
  • LoadOrStore 存在就读,不存在就写
  • Range 遍历,表示对所有key进行遍历,并将遍历出的key,value传入回调函数进行函数调用,回调函数返回false时遍历结束,否则遍历完所有key.

package main

import (
   "fmt"
   "golang.org/x/net/websocket"
   "sync"
)

// 遍历时删除所有的偶数,结果:确实删除了所有的偶数
func fun1() {
   x := sync.Map{}
   // 构建
   for i := 0; i < 100; i++ {
      x.Store(i, i)
   }
   // 遍历时删除偶数
   x.Range(func(k, v interface{}) bool {
      if k.(int)%2 == 0 {
         x.Delete(k)
      }
      return true
   })
   // 遍历打印剩下的
   cout := 0
   x.Range(func(k, v interface{}) bool {
      fmt.Println(k, v)
      cout++
      return true
   })
   // 会发现是50个,说明删除了所有的偶数
   fmt.Println("删除偶数后,剩余元素数,cout:", cout)
}

// 遍历时删除所有元素,结果:确实删除了所有的元素
func fun2() {
   x := sync.Map{}
   // 构建
   for i := 0; i < 100; i++ {
      x.Store(i, i)
   }
   // 遍历时删除偶数
   x.Range(func(k, v interface{}) bool {
      x.Delete(k)
      return true
   })
   // 遍历打印剩下的
   cout := 0
   x.Range(func(k, v interface{}) bool {
      fmt.Println(k, v)
      cout++
      return true
   })
   // 会发现是0个,说明删除了所有的元素
   fmt.Println("全部删除后,剩余元素数,cout:", cout)
}

type Game struct {
   m_UserList sync.Map
}


func main() {
   // 遍历时删除一半
   fun1()

   // 遍历时删除所有元素
   fun2()
}


//通过userId查ws
func (r *Game) FindSocketByUserID(userId int) *websocket.Conn {
   var ws *websocket.Conn
   r.m_UserList.Range(func(k, v interface{}) bool {
      switch v.(type) {
      case *websocket.Conn:
         userId_k := k.(int)
         if userId == userId_k {
            ws = v.(*websocket.Conn)
            return false//返回false表示停止遍历
         }
      }
      return true  //返回true表示继续遍历
   })
   return ws
}

//添加用户列表
func (r *Game) AddUserList(userId int, ws *websocket.Conn) {
   if vv, ok := r.m_UserList.LoadOrStore(userId, ws); ok {
      fmt.Println("添加游戏用户列表:", vv)
   }
}


//删除用户列表
func (r *Game) DelUserList(userId int) {
   r.m_UserList.Delete(userId)
}

原理分析

//todo