この記事では、PHP のジェネリックスについて説明します。まず、PHP ジェネリックスの基本的な知識を理解しましょう。次の記事では、ジェネリックスについてさらに深く理解していきます。あなたに役立ちます!
PHP のジェネリックス。これが私が望んでいることだとわかっていました。多くの開発者がこのタイプを使用することを望んでいることはわかっています。一方で、ジェネリックとは何か、またはなぜこの型があるのかを知らない PHP プログラマーも多数いるかもしれません。
このブログでは、ジェネリックと PHP に関する一連の記事を書く予定です。最初から始めましょう。すぐに、より複雑なトピックに移ります。ジェネリックとは何か、PHP がジェネリックをサポートしない理由、そして将来何が起こるかについて説明します。 ######はじめましょう。
#すべてのプログラミング言語には、何らかのシステムがあります。一部の言語は実装が非常に厳密ですが、他の言語 (PHP はこのカテゴリに分類されます) ははるかに緩いです。
さて、型システムを使用する理由はたくさんあります。最も明白なのは型検証です。 2 つの数値と 2 つの整数を受け入れ、それらに対して何らかの計算を行う関数があるとします:function add($a, $b) { return $a + $b; }PHP では、数値、文字列など、あらゆるタイプのデータを関数に渡すことができます。ブール値は関係ありません。 PHP は、変数を加算するなど、意味のある場合には変数を変換するために最善を尽くします。
add('1', '2');しかし、これらの変換 (型のジャグリング) は、予期しない結果、つまりエラーやクラッシュを引き起こすことがよくあります。
add([], true); // ?ここで、数学的加算演算が任意の入力に対して使用されることを確認するコードを手動で作成できます。
function add($a, $b) { if (!is_int($a) || !is_int($b)) { return null; } return $a + $b; }あるいは、PHPS 組み込みの型ヒントを使用することもできます。これは次のとおりです。手動で行うことの組み込みの省略表現:
function add(int $a, int $b): int { return $a + $b; }PHP コミュニティの多くの開発者は、この関数には整数のみを渡すべきであることを知っているため、これらの型ヒントはあまり気にしないと言っています。全部書いてあります。 しかし、この推論はすぐに崩れます。多くの場合、そのコードベースで作業しているのはあなただけではなく、自分で書いたわけではないコードを使用していることになります。Composer Bag をどれだけ導入したか考えてみてください。したがって、この個別の例は大したことではないように思えるかもしれませんが、コードが大きくなり始めると、型チェックが役に立ちます。 さらに、タイプヒントを追加すると、無効な状態を防ぐだけでなく、プログラマが必要とする値入力のタイプが
明確になります。関数の機能のほとんどはすでにその型定義によってカプセル化されているため、型を定義すると、通常、外部ドキュメントを読む必要がなくなります。
IDE はこの原則を多用します。つまり、関数が期待する値の入力の種類、またはオブジェクトがクラスに属しているため、オブジェクトで使用できるフィールドやメソッドをプログラマに伝えることができます。 IDE を使用すると、コード ベースの型ヒントを静的に分析できるため、コードをより効率的に作成できるようになります。 この言葉を覚えておいてください:
静的分析- これはこのシリーズの後半で非常に重要になります。これは、プログラム、IDE、または他のタイプの「静的アナライザー」がコードを調べて、実行しなくても動作するかどうかを、少なくともある程度は知らせることができることを意味します。整数のみを受け入れる関数に文字列を渡すと、IDE は何が間違っているのかを教えてくれます。これにより実行時にプログラムがクラッシュしますが、IDE はコードを実際に実行しなくても教えてくれます。
一方、型システムにも限界があります。一般的な例は「項目リスト」です: class Collection extends ArrayObject
{
public function offsetGet(mixed $key): mixed
{ /* … */ }
public function filter(Closure $fn): self
{ /* … */ }
public function map(Closure $fn): self
{ /* … */ }
}
コレクションには、ループ、フィルタリング、マッピングなど、あらゆるタイプの入力を処理するメソッドが多数あります。コレクションの実装では、文字列を処理するか整数を処理するかを気にする必要はありません。
しかし、外部の視点から見てみましょう。あるコレクションには文字列のみが含まれ、別のコレクションには「ユーザー」オブジェクトのみが含まれるようにしたい場合はどうなるでしょうか。コレクション自体は、その
itemsをループするときに気にしませんが、私たちは気にします。ループ内の項目がユーザーなのか文字列なのかを知りたいのですが、それはまったく異なります。ただし、正しい型情報がないと、IDE は未知の状況で実行されます。
$users = new Collection(); // … foreach ($users as $user) { $user-> // ? }
これで、コレクションごとに個別の実装を作成できるようになります。1 つは文字列でのみ動作する実装で、もう 1 つは User
オブジェクトでのみ動作するものです。 3 番目の実装が必要ですか?第4?たぶん10か20。これらのコードの管理は非常に困難になります。
ここでジェネリックが登場します。 明確にする必要があります: PHP にはジェネリックがありません。これはかなりの回り道を伴う大胆な発言ですが、これについてはこのシリーズの後半で説明します。しかし今、私がこれから紹介するものは PHP には存在しないと言えます。しかし、他のプログラミング言語にも存在します。
多くのプログラミング言語では、開発者は、考えられる型ごとに個別の実装を実装するのではなく、コレクション クラスで「ジェネリック」を定義できます。
class Collection<Type> extends ArrayObject { public function offsetGet(mixed $key): Type { /* … */ } // … }
基本上我们说的是集合类的实现适用于任何类型的输入,但是当我们创建集合的实例时,我们应该指定一个类型。它是一个泛型实现,需要根据程序员的需求来特定:
$users = new Collection<User>(); $slugs = new Collection<string>();
添加类型似乎是一件小事。但这种类型本身就开启了一个充满可能性的世界。 我们的 IDE 现在知道了集合中的数据类型,它可以告诉我们是否添加了错误类型的项;它可以告诉我们在迭代集合时可以对项执行什么操作;它可以告诉我们是否将集合传递给知道如何处理这些特定项的函数。
虽然我们可以通过手动为我们需要的每种类型实现一个集合,在技术上实现同样的效果;对于编写和维护代码的开发人员来说,通用实现将是一项重大改进。
那么,我们为什么不在 PHP 中使用泛型呢?除了无聊的收藏,我们还能用它们做什么?我们能为他们增加支持吗?我们将在这个系列中回答所有这些问题。首先需要澄清的是:我在本系列文章中的目标是教你关于泛型的知识,但同样重要的是,我想让大家意识到我们是如何误解 PHP 的。我想改变这种状况。
英文原文地址:https://stitcher.io/blog/generics-in-php-1
推荐:《PHP视频教程》
以上がPHP のジェネリックの基礎知識について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。