dongza3124 2015-03-03 09:40
浏览 302
已采纳

有没有一种方法可以编写通用代码来确定切片是否包含Go中的特定元素?

I want to know is there a generic way to write code to judge whether a slice contains an element, I find it will frequently useful since there is a lot of logic to fist judge whether specific elem is already in a slice and then decide what to do next. But there seemed not a built-in method for that(For God's sake, why?)

I try to use interface{} to do that like:

func sliceContains(slice []interface{}, elem interface{}) bool {
    for _, item := range slice {
       if item == elem {
          return true
       }
    }
    return false
}

I thought interface{} is sort of like Object of Java, but apparently, I was wrong. Should I write this every time meet with a new struct of slice? Isn't there a generic way to do this?

  • 写回答

4条回答 默认 最新

  • duanlu1922 2015-03-03 10:18
    关注

    You can do it with reflect, but it will be MUCH SLOWER than a non-generic equivalent function:

    func Contains(slice, elem interface{}) bool {
    
        sv := reflect.ValueOf(slice)
    
        // Check that slice is actually a slice/array. 
        // you might want to return an error here
        if sv.Kind() != reflect.Slice && sv.Kind() != reflect.Array {
            return false
        }
    
        // iterate the slice
        for i := 0; i < sv.Len(); i++ {
    
            // compare elem to the current slice element
            if elem == sv.Index(i).Interface() {
                return true
            }
        }
    
        // nothing found
        return false
    
    
    }
    
    func main(){
        si := []int {3, 4, 5, 10, 11}
        ss := []string {"hello", "world", "foo", "bar"}
    
        fmt.Println(Contains(si, 3))
        fmt.Println(Contains(si, 100))
        fmt.Println(Contains(ss, "hello"))
        fmt.Println(Contains(ss, "baz"))
    
    }
    

    How much slower? about x50-x60 slower: Benchmarking against a non generic function of the form:

    func ContainsNonGeneic(slice []int, elem int) bool {
        for _, i := range slice {
            if i == elem {
                return true
            }
        }
        return false
    }
    

    I'm getting:

    • Generic: N=100000, running time: 73.023214ms 730.23214 ns/op
    • Non Generic: N=100000, running time: 1.315262ms 13.15262 ns/op
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器