Go スライス内の要素の存在を判断するために汎用コードを実装できますか?
Go では、スライスに特定の要素が含まれているかどうかを判断します。共通の操作。ただし、新しいスライス タイプごとに、このロジックの実装は面倒に思えるかもしれません。
試みられた解決策の 1 つは、コード スニペットに見られるように、interface{} スライスを使用することです。
<code class="go">func sliceContains(slice []interface{}, elem interface{}) bool { for _, item := range slice { if item == elem { return true } } return false }</code>
ただし、このアプローチは、インターフェースの性質と、新しいスライス タイプごとにインターフェースを実装する必要があるため、妨げられます。
幸いなことに、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>
この関数スライスと検索する要素という 2 つのパラメータを取ります。リフレクションを使用して、スライスがスライスであるか配列であるかを判断し、その後、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 の Reflection パッケージはスライス内の汎用要素の存在チェックを有効にできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。