ホームページ >バックエンド開発 >Golang >Go の Reflection パッケージはスライス内の汎用要素の存在チェックを有効にできますか?

Go の Reflection パッケージはスライス内の汎用要素の存在チェックを有効にできますか?

Linda Hamilton
Linda Hamiltonオリジナル
2024-11-03 09:53:29911ブラウズ

Can Go's Reflection Package Enable Generic Element Presence Checks in Slices?

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>

ベンチマーク結果:

  • ジェネリック: N=100000、73.023214ms、730.23214 ns/op
  • 非ジェネリック: N=100000、1.315262ms、13.15262 ns/op

したがって、ジェネリック Contains() 関数多用途性を提供しますが、パフォーマンスのボトルネックを避けるために慎重に使用する必要があります。

以上がGo の Reflection パッケージはスライス内の汎用要素の存在チェックを有効にできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。