可以实现通用代码来判断 Go 切片中是否存在元素吗?
在 Go 中,判断切片是否包含特定元素是一个共同操作。然而,对于每种新的切片类型,实现此逻辑似乎很乏味。
一种尝试的解决方案涉及使用 interface{} 切片,如代码片段中所示:
<code class="go">func sliceContains(slice []interface{}, elem interface{}) bool { for _, item := range slice { if item == elem { return true } } return false }</code>
但是,这种方法受到interface{}的性质以及为每个新切片类型实现它的要求的阻碍。
幸运的是,Go的反射包提供了一个通用的解决方案:
<code class="go">func Contains(slice, elem interface{}) bool { sv := reflect.ValueOf(slice) // Check slice type. if sv.Kind() != reflect.Slice && sv.Kind() != reflect.Array { return false } // Iterate slice and compare elements. for i := 0; i < sv.Len(); i++ { if elem == sv.Index(i).Interface() { return true } } // Element not found. return false }</code>
这个函数有两个参数:切片和要查找的元素。它使用反射来确定切片是切片还是数组,然后使用 ValueOf() 和 Index() 方法迭代其元素。
虽然这种通用方法很方便,但其代价是表现。基准测试显示,它可能比非通用版本慢 50-60 倍,如下所示:
<code class="go">func ContainsNonGeneic(slice []int, elem int) bool { for _, i := range slice { if i == elem { return true } } return false }</code>
基准测试结果:
因此,虽然泛型 Contains() 函数提供了多功能性,但应谨慎使用以避免性能瓶颈。
以上是Go 的反射包可以启用切片中的通用元素存在检查吗?的详细内容。更多信息请关注PHP中文网其他相关文章!