Go 1.18 で導入されたジェネリックは、再利用可能でタイプセーフなコードを記述する方法に革命をもたらしました。ジェネリックは Go のシンプルさの哲学を維持しながら、柔軟性とパワーをもたらします。ただし、ニュアンスや利点、ジェネリックと従来のアプローチ (interface{} など) との比較を理解するには、詳しく調べる必要があります。
ジェネリックの複雑さを調べ、制約を詳しく調べ、ジェネリックとインターフェースを比較して、実際のアプリケーションをデモンストレーションしましょう。{}パフォーマンスに関する考慮事項とバイナリ サイズへの影響についても触れます。飛び込んでみましょう!
ジェネリックとは何ですか?
開発者は、ジェネリックを使用して、型の安全性を維持しながら任意の型で動作できる関数とデータ構造を作成できます。実行時に型アサーションを必要とするインターフェース{}に依存する代わりに、ジェネリックを使用すると、型に対して許可される操作を指示する一連の制約を指定できます。
構文
func FunctionName[T TypeConstraint](parameterName T) ReturnType { // Function body using T }
T: 型のプレースホルダーを表す型パラメーター。
TypeConstraint: T の型を特定の型または型のセットに制限します。
parameterName T: パラメーターはジェネリック型 T を使用します。
ReturnType: この関数は、型 T の値を返すこともできます。
例
func Sum[T int | float64](a, b T) T { return a + b }
func Sum: 関数の名前 Sum
を宣言します。[T int | float64]: 特定の型 (int または float64) に制限された、型パラメーターとして T を導入する型パラメーター リストを指定します。 Sum 関数は、int または float64 のいずれかのパラメーターのみを受け取り、組み合わせることはできません。両方とも int または float64 のいずれかでなければなりません。これについては、以下のセクションでさらに詳しく説明します。
(a, b T): 2 つのパラメーター a と b を宣言します。どちらも型 T (ジェネリック型) ).
T: 型パラメータ T に一致する関数の戻り型を指定します。
制約: ジェネリックの構成要素
制約は、ジェネリック型に対してどのような操作が有効であるかを定義します。 Go は、実験的な制約パッケージ (golang.org/x/exp/constraints) などの制約用の強力なツールを提供します。
組み込みの制約
Go では、型安全性を提供すると同時に、再利用可能なジェネリック コードを柔軟に定義できるように、ジェネリックを使用した組み込み制約を導入しました。これらの制約により、開発者はジェネリック関数または型で使用される型にルールを適用できます。
Go には以下の組み込み制約があります
- any: 任意の型を表します。これはインターフェースのエイリアスです。{}これは制約が必要ない場合に使用されます
func FunctionName[T TypeConstraint](parameterName T) ReturnType { // Function body using T }
- comparable: 等価比較 (== および !=) をサポートする型を許可します。マップキー、重複検出、または等価性チェックに役立ちます。これらの型は直接比較をサポートしていないため、これはマップ、スライス、関数には使用できません。
func Sum[T int | float64](a, b T) T { return a + b }
実験上の制約
- constraints.Complex: 複素数値型 (complex64 および complex128) を許可します。
- constraints.Float: float 数値型 (float32 および float64) を許可します
- constraints.Integer: 符号付きおよび符号なしの両方の整数を許可します (int8、int16、int32、int64、int、uint8、uint16、uint32、uint64、および uint)
- constraints.Signed: 任意の符号付き整数 (int8、int16、int32、int64、および int) を許可します
- constraints.Unsigned: 任意の符号なし整数 (uint8、uint16、uint32、uint64、および uint) を許可します。
- constraint.Ordered: 比較を許可する型 (<.>、>=)、すべての数値型と文字列がサポートされます (int、float64、string など)。
func PrintValues[T any](values []T) { for _, v := range values { fmt.Println(v) } }
カスタム制約
カスタム制約は、ジェネリック型パラメーターが満たさなければならない型または型の動作のセットを定義するインターフェイスです。独自の制約を作成することで、次のことが可能になります。
数値型など、型を特定のサブセットに制限します。
特定のメソッドまたは動作を実装するには型が必要です。
汎用関数と型にさらに制御性と特異性を追加します。
構文
func CheckDuplicates[T comparable](items []T) []T { seen := make(map[T]bool) duplicates := []T{} for _, item := range items { if seen[item] { duplicates = append(duplicates, item) } else { seen[item] = true } } return duplicates }
例
import ( "golang.org/x/exp/constraints" "fmt" ) func SortSlice[T constraints.Ordered](items []T) []T { sorted := append([]T{}, items...) // Copy slice sort.Slice(sorted, func(i, j int) bool { return sorted[i] <p><strong><em>Sum 関数</em></strong> は、int、int64、float64 パラメーターのみを使用して呼び出すことができます。</p> <h3> メソッド別の制約 </h3> <p>型に特定のメソッドを実装する必要がある場合は、それらのメソッドを使用して型を定義できます。<br> </p> <pre class="brush:php;toolbar:false">type Numeric interface { int | float64 | uint }
Formatter 制約では、T として使用される型には、文字列.
制約の結合カスタム制約は型セットとメソッド要件を組み合わせることができます
type Number interface { int | int64 | float64 } func Sum[T Number](a, b T) T { return a + b }この制約には両方の特定の型 (
int、float54) が含まれており、abs メソッドの存在が必要です。
ジェネリックとインターフェース{}ジェネリックの導入前は、柔軟性を実現するためにインターフェイス{}が使用されていました。ただし、このアプローチには制限があります。
タイプセーフティ
- インターフェース{}: 実行時の型アサーションに依存するため、実行時にエラーが発生する可能性が高くなります。
- ジェネリック: コンパイル時の型安全性を提供し、開発中の早期にエラーをキャッチします。
パフォーマンス
インターフェース{}: 追加のランタイム型チェックにより速度が低下します。
ジェネリック: コンパイラーが型に固有の最適化されたコード パスを生成するため、高速になります。
コードの可読性
インターフェース{}: 多くの場合冗長で直感的ではないため、コードの保守が難しくなります。
ジェネリック: よりクリーンな構文により、コードがより直感的で保守しやすくなります。
バイナリサイズ
インターフェース{}: 異なるタイプのコードを複製しないため、バイナリが小さくなります。
ジェネリック: パフォーマンス向上のための型の特殊化により、バイナリ サイズがわずかに増加します。
例
func FunctionName[T TypeConstraint](parameterName T) ReturnType { // Function body using T }
コードは正常に機能しますが、型アサーションはオーバーヘッドです。 Add 関数は任意の引数を指定して呼び出すことができます。a パラメータと b パラメータは両方とも異なる型にすることができますが、コードは実行時にクラッシュします。
func Sum[T int | float64](a, b T) T { return a + b }
ジェネリックにより、不正な型アサーションによって引き起こされる実行時パニックのリスクが排除され、明確さが向上します。
パフォーマンス
ジェネリックは各タイプに特化したコードを生成するため、インターフェース{}と比較して実行時のパフォーマンスが向上します。
バイナリサイズ
トレードオフが存在します。ジェネリックスでは、型ごとにコードが重複するためバイナリ サイズが増加しますが、これは多くの場合、利点に比べれば無視できるものです。
Go ジェネリックの制限
制約の複雑さ:constraints.Ordered のような制約は一般的な使用例を単純化しますが、高度にカスタマイズされた制約の定義は冗長になる可能性があります。
構造体には型推論がありません: 関数とは異なり、構造体には型パラメーターを明示的に指定する必要があります。
func PrintValues[T any](values []T) { for _, v := range values { fmt.Println(v) } }
コンパイル時の制約に限定: Go ジェネリックスはコンパイル時の安全性に焦点を当てていますが、Rust のような言語はライフタイムとトレイトを使用したより強力な制約を提供します。
ベンチマークをしましょう — 言うよりもやったほうが良い
インターフェースと汎用の両方を備えたシンプルなキューを実装し、結果をベンチマークします。
インターフェース{} キューの実装
func CheckDuplicates[T comparable](items []T) []T { seen := make(map[T]bool) duplicates := []T{} for _, item := range items { if seen[item] { duplicates = append(duplicates, item) } else { seen[item] = true } } return duplicates }
汎用キューの実装
import ( "golang.org/x/exp/constraints" "fmt" ) func SortSlice[T constraints.Ordered](items []T) []T { sorted := append([]T{}, items...) // Copy slice sort.Slice(sorted, func(i, j int) bool { return sorted[i] <pre class="brush:php;toolbar:false">type Numeric interface { int | float64 | uint }
結果の分析
実行時間:
汎用実装は、実行時の型アサーションを回避し、指定された型で直接動作するため、インターフェイス バージョンよりも約 63.64% 高速です。割り当て:
インターフェースのバージョンでは、主に値の挿入および取得時のボックス化/ボックス化解除により、3 倍多くの割り当てが行われます。{}これにより、ガベージ コレクションにオーバーヘッドが追加されます。
100 万回のエンキュー/デキュー操作など、より大きなワークロードの場合、パフォーマンスのギャップは拡大します。高スループット要件を持つ現実世界のアプリケーション (メッセージ キュー、ジョブ スケジューラなど) は、ジェネリックから大きな恩恵を受けます。
最終的な考え
Go のジェネリックスは、パワーとシンプルさのバランスをとり、再利用可能でタイプセーフなコードを作成するための実用的なソリューションを提供します。 Rust や C ほど機能が豊富ではありませんが、Go のミニマリスト哲学と完全に一致しています。 Constraints.Ordered などの制約を理解し、ジェネリックを効果的に活用することで、コードの品質と保守性を大幅に向上させることができます。
ジェネリックは進化し続けるため、Go のエコシステムで中心的な役割を果たすことになります。 Go プログラミングにおける型安全性と柔軟性の新時代を体験し、実験し、受け入れてください!
ジェネリックに関するいくつかのサンプルについては、github リポジトリをチェックアウトしてください。
サダナンドダワダカール
/
ゴージェネリクス
リポジトリには go ジェネリックの動作例が含まれています
Go Generics: 包括的なサンプル リポジトリ
Go ジェネリック リポジトリ へようこそ!このリポジトリは、バージョン 1.18 で導入された Go のジェネリックスを理解し、学習し、習得するためのワンストップ リソースです。ジェネリックは Go に型パラメーターの機能をもたらし、開発者がパフォーマンスや読みやすさを犠牲にすることなく、再利用可能で型安全なコードを作成できるようにします。
このリポジトリには、基本的な構文から高度なパターン、実用的な使用例まで、幅広いトピックをカバーする慎重に厳選された例が含まれています。初心者でも経験豊富な Go 開発者でも、このコレクションはプロジェクトでジェネリックを効果的に活用するのに役立ちます。
?中身は何ですか
?基本的な汎用プログラム
これらの例では、ジェネリックスの基本的な概念を紹介し、構文とコア機能を理解するのに役立ちます。
- GenericMap: 任意のタイプのスライスを変換する汎用マップ関数を示します。
- Swap: 2 つの値を一般的に交換する、シンプルかつ強力な例です。
- FilterSlice: フィルタリングする方法を示します…
以上がGo のジェネリックス: コードの再利用性を変革するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

GOでは、ミューテックスとロックを使用することが、スレッドの安全性を確保するための鍵です。 1)相互に排他的なアクセスにsync.mutexを使用し、2)読み取りおよび書き込み操作にsync.rwmutexを使用します。これらのツールとその使用スキルをマスターすることは、効率的で信頼できる同時プログラムを作成するために不可欠です。

同時GOコードのパフォーマンスを最適化する方法は? GOEST、GOBENCH、PPROFなどのGOの組み込みツールを使用して、ベンチマークやパフォーマンス分析を行います。 1)テストパッケージを使用してベンチマークを書き込み、同時関数の実行速度を評価します。 2)PPROFツールを使用して、パフォーマンス分析を実行し、プログラム内のボトルネックを特定します。 3)ガベージ収集設定を調整して、パフォーマンスへの影響を減らします。 4)チャネル動作を最適化し、ゴルチンの数を制限して効率を改善します。継続的なベンチマークとパフォーマンス分析により、同時GOコードのパフォーマンスを効果的に改善できます。

同時GOプログラムでのエラー処理の一般的な落とし穴を回避する方法には、次のものが含まれます。1。エラー伝播、2。処理タイムアウト、3。集約エラー、4。コンテキスト管理、5。エラーラッピング、6。ロギング、7。テスト。これらの戦略は、同時環境でエラーを効果的に処理するのに役立ちます。

inclicitInterfaceImplementationingombodiesducktypingtosatisistosistosInterfaces withoutexplicitdeclaration.1)itPromotesflexulivyby byfocusingonbehavior.2)

GOプログラミングでは、エラーを効果的に管理する方法には、1)例外の代わりにエラー値の使用、2)エラーラッピング技術の使用、3)カスタムエラータイプの定義、4)パフォーマンスの再利用、パフォーマンスと回復の使用、5)エラーメッセージは明確で一貫性があることを保証する、7)エラーの処理を補うエラーこれらのプラクティスとパターンは、より堅牢で保守可能で効率的なコードを書き込むのに役立ちます。

GORoutinesとチャンネルを使用して、GOで同時性を実装できます。 1)音楽を楽しんだり、同時に友人を観察したりするなど、ゴルチンを使用して並行してタスクを実行します。 2)生産者モデルや消費者モデルなどのチャネルを介してゴルチン間でデータを安全に転送します。 3)ゴルチンやデッドロックの過度の使用を避け、同時プログラムを最適化するためにシステムを合理的に設計します。

goooffersmultipreapproaches forbuildingconcurreantdatastructures(mutexes、channels、andatomicoperations.1)mutexexexexexexexexexexexexexprovidesimprovidesedsafetybutcancauseperformancebottlenecks.2)チャネルオフェルスケーリビリティButmaybutlorempty.3)

goserrorhandlingisexplicit、treatingErrorsassedededededededededectectionsは、pythonandjava.1とは異なります


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

ドリームウィーバー CS6
ビジュアル Web 開発ツール

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター
