この記事では、PHP のジェネリックスについて詳しく理解し、2 つの一般的な例を紹介します。お役に立てば幸いです。
前の記事で非常に退屈なジェネリックスを示しました。例として、これはもっとうまくいくだろう。
$users = new Collection<User>(); $slugs = new Collection<string>();
コレクション
これらはおそらくジェネリックを説明する最も簡単な方法ですが、ジェネリックについて議論するときに誰もが話題にする例でもあります。人々は、「ジェネリック」と「型付きコレクション」を同じものとして考えることがよくあります。絶対にそうではありません。
それでは、さらに 2 つの例を見てみましょう。
これは「app」と呼ばれる関数です。Laravel などのフレームワークを使用している場合は、見覚えがあるかもしれません。この関数はクラス名を受け取り、依存するコンテナーを使用してそのクラスのインスタンスを解決します:
function app(string $className): mixed { return Container::get($className); }
さて、コンテナがどのように機能するかを知る必要はありません。重要なことは、この関数が要求したクラスのインスタンスを提供するということです。
つまり、これは基本的にジェネリック関数であり、戻り値の型は指定したクラス名によって異なります。この関数に「UserRepository」というクラス名を付けた場合、UserRepository のインスタンスだけが返され、それ以外は何も返されないことを IDE や他の静的アナライザーも理解できれば素晴らしいでしょう。これを行う。
私は、このように秘密にしていたことを話す良い機会だと思いました: 前回の投稿で、PHP にはジェネリックが存在しないと述べましたが、それは完全に真実ではありません。世に出ているすべての静的アナライザー - コードを実行せずに読み取るツール、IDE などのツール - ジェネリックスに doc ブロックのコメントを使用できるようにします:
function app(string $className): mixed { /* … */ } app(UserRepository::class); // ?
確かに、これは最も完璧な構文ではなく、すべて静的です。アナライザーは単純なプロトコルに依存しているため、公式の正規構文はありませんが、機能します。 PHP の世界で最大の 3 つの静的アナライザー、PhpStorm、Psalm、および PhpStan はすべて、この構文をある程度理解しています。
PhpStorm などの IDE は、コードを作成するプログラマにフィードバックを提供するためにこれを使用し、Psalm や PhpStan などのツールは、コード ベースを一括分析し、潜在的なバグを検出するためにこれを使用します (主に型定義に基づいています)。
つまり、実際には、この
app 関数を構築して、ツールが暗闇の中で実行されないようにすることができます。もちろん、PHP は実行時に関数の型チェックをしないため、PHP 自体は戻り値の型が正しいことを保証できませんが、静的アナライザーが正しいと信頼できる場合は、実行時にこの段落のコードはほとんどありません。 - 中断される可能性はありません。 これが静的分析の驚異的な力です。コードを実行しなくても、コードのほとんどが期待どおりに動作することを実際に確認できます。これはすべて、ジェネリックを含む型のおかげで可能になります。
より複雑な例を見てみましょう:
/** * @template Type * @param class-string<Type> $className * @return Type */ function app(string $className): mixed { /* … */ }
ここには、プロパティを「クエリ」し、その場でインスタンス化できるクラスがあります。リフレクション API が非常に冗長であることを知る前にプロパティを使用したことがある場合、このヘルパー クラスは非常に便利だと思います。
filter メソッドを使用する場合、プロパティのクラス名を指定し、結果がインスタンスになることを認識して newInstance
メソッドを呼び出します。フィルタクラスの .繰り返しになりますが、IDE が私たちが話していることを理解できれば素晴らしいと思います。 おわかりでしょう: ジェネリックを使用すると、次のことが可能になります:
Attributes::in(MyController::class) ->filter(RouteAttribute::class) ->newInstance() ->
単純な型情報の威力がわかっていただければ幸いです。数年前、これらの分析情報を機能させるには IDE プラグインが必要でしたが、今では型情報を追加するだけで済みます。
ただし、この最新の例はジェネリックに依存しているだけではなく、別の同様に重要な部分が関与しています。型推論: ユーザーが指定しなくても型を「推測」する (つまり確実に決定する) 静的アナライザーの機能。それが、文字列のような注釈で起こっていることです。私たちの IDE は、この関数に提供した入力をクラス名として認識し、型をジェネリック型として推論できます。
これで、すべて解決です。PHP にはジェネリックがあり、すべての主要な静的アナライザーはその使用方法を知っています。そうですね...注意点がいくつかあります。
まず第一に、ジェネリックがどのようなものであるべきかについての公式仕様はありません。現在、各静的アナライザーは独自の構文を使用できます。現時点では、それらのうちの 1 つにたまたま合意していますが、将来はほとんど保証されていません。 。
第二に、私の意見では、ドキュメント ブロックは最適とは言えません。私たちのコードベースでは、それらはそれほど重要ではないと感じます。もちろん、汎用アノテーションは静的な洞察のみを提供し、実行時機能は提供しませんが、実行時の型チェックがなくても静的分析の威力が確認できました。型情報を「ドキュメントのコメント」と考えるのは不公平だと思います。コードにおけるこれらの型の重要性が伝わりません。それが、PHP8 で属性を導入した理由です。属性によって提供されるすべての機能は、docblock コメントで可能でしたが、それだけでは十分ではないと感じました。ジェネリック医薬品も同様です。
最後の注意: 適切な仕様がなければ、3 つの主要な静的アナライザーはすべて、汎用実装間で差異が生じます。現時点で最も不足しているのは PhpStorm です。理想的には、PHP 内から正式な仕様が存在することです。しかし、まだ正式なものはありません。
これらが、より長く持続する、より持続可能なソリューションに時間を投資する価値があると私が考える主な理由です。では、なぜ PHP にはまだ適切なジェネリックがないのでしょうか?なぜ明確な仕様のないドキュメントの塊に依存するのでしょうか?
元のアドレス: https://stitcher.io/blog/generics-in-php-2
翻訳アドレス: https://learnku.com/php/t/ 66484
推奨: 「PHP ビデオ チュートリアル 」
以上がPHP のジェネリックについて例を挙げて詳しく学びますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。