showliuzp 2025-11-01 12:54 采纳率: 84.3%
浏览 2
已结题

golang通用顺序查找


func slice_find(targe int64,src *[]int64) (res string){
    for i,count := 0,len(list);i < count;i++{
        if targe == (*src)[i].Id{
            res = (*src)[i].Title
            break
        }
    }

    return
}


我想做个顺序查找的通用封装,targe值有可能是int64string,src有可能是[]int64,[]string,[]struct,返回值有可能是intstring类型,但在比较的过程中不要侵入
应该做?

我大体写了下:
func slice_find(targe interface{},src *interface{},compare func()bool) (res interface){
    for i,count := 0,len(list);i < count;i++{
        if compare(targe,(*src)[i].Id){
            res = (*src)[i].Title, //具体返回哪个字段应该是可以自定义的
            break
        }
    }

    return
}

  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-11-01 13:16
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:每一个不曾放弃的瞬间,都在为未来积蓄力量。
    .

    基于你的需求,我来为你提供一个更完善的通用顺序查找实现。你的思路是正确的,使用接口和比较函数来实现通用性,但有几个关键点需要改进:

    // 通用顺序查找函数
    func SliceFind(target interface{}, src interface{}, 
        compareFunc func(target interface{}, elem interface{}) bool,
        resultFunc func(elem interface{}) interface{}) interface{} {
        
        srcSlice := reflect.ValueOf(src)
        if srcSlice.Kind() != reflect.Slice {
            return nil
        }
        
        length := srcSlice.Len()
        for i := 0; i < length; i++ {
            elem := srcSlice.Index(i).Interface()
            if compareFunc(target, elem) {
                return resultFunc(elem)
            }
        }
        
        return nil
    }
    

    使用示例

    1. 查找整数切片

    func main() {
        // 示例1:在 []int64 中查找
        intSlice := []int64{1, 2, 3, 4, 5}
        
        compareInt := func(target interface{}, elem interface{}) bool {
            return target.(int64) == elem.(int64)
        }
        
        resultInt := func(elem interface{}) interface{} {
            return elem
        }
        
        found := SliceFind(int64(3), intSlice, compareInt, resultInt)
        fmt.Println(found) // 输出: 3
    }
    

    2. 查找字符串切片

    // 示例2:在 []string 中查找
    stringSlice := []string{"apple", "banana", "orange"}
    
    
    compareString := func(target interface{}, elem interface{}) bool {
        return target.(string) == elem.(string)
    }
    
    
    resultString := func(elem interface{}) interface{} {
        return elem
    }
    
    
    foundStr := SliceFind("banana", stringSlice, compareString, resultString)
    fmt.Println(foundStr) // 输出: banana
    

    3. 查找结构体切片

    // 示例3:在结构体切片中查找
    type Product struct {
        ID    int64
        Name  string
        Price float64
    }
    
    
    products := []Product{
        {1, "Laptop", 999.99},
        {2, "Mouse", 29.99},
        {3, "Keyboard", 79.99},
    }
    
    
    // 按ID查找
    compareByID := func(target interface{}, elem interface{}) bool {
        return target.(int64) == elem.(Product).ID
    }
    
    
    resultByName := func(elem interface{}) interface{} {
        return elem.(Product).Name
    }
    
    
    productName := SliceFind(int64(2), products, compareByID, resultByName)
    fmt.Println(productName) // 输出: Mouse
    
    
    // 按名称查找
    compareByName := func(target interface{}, elem interface{}) bool {
        return target.(string) == elem.(Product).Name
    }
    
    
    resultByPrice := func(elem interface{}) interface{} {
        return elem.(Product).Price
    }
    
    
    productPrice := SliceFind("Keyboard", products, compareByName, resultByPrice)
    fmt.Println(productPrice) // 输出: 79.99
    

    更简洁的封装

    如果你想要更简洁的调用方式,可以创建特定类型的包装函数:

    // 针对特定类型的包装函数
    func FindInInt64Slice(slice []int64, target int64) *int64 {
        result := SliceFind(target, slice,
            func(t, e interface{}) bool { return t.(int64) == e.(int64) },
            func(e interface{}) interface{} { return e })
        
        if result != nil {
            val := result.(int64)
            return &val
        }
        return nil
    }
    
    
    func FindInStructSliceByID(slice []Product, targetID int64) *string {
        result := SliceFind(targetID, slice,
            func(t, e interface{}) bool { return t.(int64) == e.(Product).ID },
            func(e interface{}) interface{} { return e.(Product).Name })
        
        if result != nil {
            val := result.(string)
            return &val
        }
        return nil
    }
    

    关键改进点

    1. 移除了指针参数:直接使用 interface{} 更符合Go的惯用法
    2. 使用反射:正确处理任意类型的切片
    3. 分离比较逻辑compareFunc 负责比较,resultFunc 负责提取结果
    4. 类型安全:在具体使用时进行类型断言,保持核心函数的通用性
    5. 返回 nil:未找到时返回 nil,调用方可以方便地检查

    这种设计保持了良好的通用性,同时避免了侵入性,你可以根据需要自定义比较和结果提取逻辑。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 11月9日
  • 已采纳回答 11月1日
  • 创建了问题 11月1日