//聊天数据结构定义
//聊天websocket连接数据结构定义
type chat_websocket_conn struct{
user_conn *tools.WebSocketConn //已建立的客户端连接,lu_guild_account_list表id
client_id string //生成的唯一id,标识一个客户端
user_type int //用户类型,1:会员 2:主播
user_id int64 //用户id
user_nickname string //用户昵称
}
//链表定义
package tools
import (
"sync"
"fmt"
)
//并发安全单链表
type SingleNode struct {
Data interface{}
Next *SingleNode
}
type SingleList struct {
Mutex *sync.RWMutex //读写锁
Head *SingleNode //头节点
Tail *SingleNode //尾节点
Size uint //总数
}
func NewLinkedList() *SingleList {
return &SingleList{
Size: 0,
Head: nil,
Tail: nil,
Mutex: new(sync.RWMutex),
}
}
//后插元素
func (List *SingleList) LastAppend(node *SingleNode) bool {
if node == nil {
return false
}
List.Mutex.Lock()
defer List.Mutex.Unlock()
if List.Size == 0 {
List.Head = node
List.Tail = node
List.Size = 1
return true
}
tail := List.Tail
tail.Next = node
List.Tail = node
List.Size += 1
return true
}
//删除链表中的指定值节点,通过回调函数实现无侵入删除
func (List *SingleList) DelLinkedNode(f func(data interface{}) bool) bool {
if List.Size == 0 {
return false
}
List.Mutex.Lock()
defer List.Mutex.Unlock()
var prev *SingleNode = nil
current := List.Head
for current != nil {
if f(current.Data){
if prev == nil {
List.Head = current.Next
} else {
prev.Next = current.Next
}
List.Size--
if List.Size == 0 {
List.Tail = nil
}
return true
}
prev = current
current = current.Next
}
prev = nil
return false
}
//查找链表中是否有指定值节点,通过回调函数实现无侵入查找
func (List *SingleList) FindLinkedNode(f func(data interface{}) bool) bool {
if List.Size == 0 {
return false
}
List.Mutex.Lock()
defer List.Mutex.Unlock()
current := List.Head
var count uint = 0
for current != nil {
if !f(current.Data){
count++
}
current = current.Next
}
if count >= List.Size{
return false
}
return true
}
//查找每个主播|会员的链表节点是否存在,根据生成的clientid
//作为回调函数传入链表,通过闭包函数实现无侵入校验
func find_linked_node_userid(user_id int64) func(interface{}) bool {
return func(data interface{}) bool{
//强制类型转换
conn, ok := data.(chat_websocket_conn)
if ok && conn.user_id == user_id {
return true
}
return false
}
}
//调用:
item := chat_websocket_conn{
user_conn : tools.WebSocketConnMapOnce.ConnMap[client_id],
client_id : *client_id,
user_type : (*user_info).Flag,
user_id : (*user_info).Id,
user_nickname : (*user_info).NickName,
}
linked_node := tools.SingleNode{Data:item}
tools.NewLinkedLis.LastAppend(&linked_node)
tools.NewLinkedList().FindLinkedNode(find_linked_node_userid(client_id))
tools.NewLinkedList().FindLinkedNode(find_linked_node_clientid(user_id))
find_linked_node_userid、find_linked_node_clientid为回调的闭包函数,仅仅是 if ok && conn.client_id == *client_id/ if ok && conn.user_id == user_id ,这里不一样,逻辑都是一样的,我想把他们封装成通用的,应该怎么封装?
golang链表查找封装
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
3条回答 默认 最新
关注让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。
如果答案让您满意,请采纳、点赞、关注,非常感谢!
.
每日一句正能量,让它带给您好心情:把生活过得热气腾腾,就是最好的状态。
.根据你的需求,可以将查找函数封装成一个通用的工厂函数,通过参数指定要比较的字段和值。以下是改进方案:
通用查找函数封装
// 通用查找条件类型 type FindCondition struct { FieldName string // 字段名: "user_id" 或 "client_id" Value interface{} // 要比较的值 } // 通用查找函数生成器 func CreateFindFunc(condition FindCondition) func(interface{}) bool { return func(data interface{}) bool { conn, ok := data.(chat_websocket_conn) if !ok { return false } switch condition.FieldName { case "user_id": if intValue, ok := condition.Value.(int64); ok { return conn.user_id == intValue } case "client_id": if strValue, ok := condition.Value.(string); ok { return conn.client_id == strValue } default: return false } return false } }使用示例
// 查找指定用户ID findFunc1 := CreateFindFunc(FindCondition{ FieldName: "user_id", Value: int64(12345), }) found1 := tools.NewLinkedList().FindLinkedNode(findFunc1) // 查找指定客户端ID findFunc2 := CreateFindFunc(FindCondition{ FieldName: "client_id", Value: "client_abc123", }) found2 := tools.NewLinkedList().FindLinkedNode(findFunc2)更灵活的封装方案
如果你需要支持更多字段,可以使用反射来实现更通用的方案:
import "reflect" // 使用反射的通用查找函数 func CreateFindFuncByReflect(fieldName string, expectedValue interface{}) func(interface{}) bool { return func(data interface{}) bool { conn, ok := data.(chat_websocket_conn) if !ok { return false } // 使用反射获取字段值 v := reflect.ValueOf(conn) field := v.FieldByName(fieldName) if !field.IsValid() { return false } // 比较字段值 return reflect.DeepEqual(field.Interface(), expectedValue) } }使用反射版本的示例
// 查找用户ID findFunc1 := CreateFindFuncByReflect("user_id", int64(12345)) found1 := tools.NewLinkedList().FindLinkedNode(findFunc1) // 查找客户端ID findFunc2 := CreateFindFuncByReflect("client_id", "client_abc123") found2 := tools.NewLinkedList().FindLinkedNode(findFunc2) // 查找用户类型 findFunc3 := CreateFindFuncByReflect("user_type", 1) found3 := tools.NewLinkedList().FindLinkedNode(findFunc3)建议
- 推荐使用第一种方案(基于switch-case),性能更好,类型安全
- 如果字段数量固定且不多,第一种方案更合适
- 如果需要动态支持任意字段,可以使用反射方案
- 可以在
FindCondition中添加比较操作符支持(等于、不等于等)来增强灵活性
这样封装后,你只需要一个函数就能处理所有字段的查找需求,代码更加简洁和可维护。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报