How to Generically Check for Element Presence in a Slice in Go
In Go, determining whether a slice contains a specific element can be a common scenario. However, there is no built-in method to perform this generic check across different slice types.
Failed Attempt with Interface{}
An attempt to use the interface{} type as a generic solution, as shown below, may seem plausible:
<code class="go">func sliceContains(slice []interface{}, elem interface{}) bool { for _, item := range slice { if item == elem { return true } } return false }</code>
However, comparing values of different types (interface{}) can lead to incorrect results.
Generic Solution with Reflection
To achieve a truly generic solution, reflection can be employed. The following function uses reflection to iterate over the slice and compare each element to the target element:
<code class="go">func Contains(slice, elem interface{}) bool { sv := reflect.ValueOf(slice) // Check that slice is actually a slice/array. 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 }</code>
This solution allows you to perform generic element checks on slices of any type.
Performance Considerations
While the generic Contains function provides the desired functionality, it comes at a significant performance cost. Benchmarking against a non-generic equivalent function yields a slowdown factor of approximately 50x. Therefore, it is crucial to evaluate the performance implications before using reflection for generic element checks.
The above is the detailed content of How do you check for element presence in slices of different types in Go?. For more information, please follow other related articles on the PHP Chinese website!