PHP中的泛型:为什么需要以及如何使用(附示例)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP 中的 Generics:为什么需要以及如何使用



现代 PHP 开发不仅需要速度,还需要代码的可靠性。实现这一目标的工具之一是 Generics(泛型)。尽管 PHP 是一种动态类型语言,但随着 PHP 7.0 及更高版本,特别是 PHP 8.0 的发布,静态类型变得可用且受欢迎。Generics 允许编写更灵活、可重用且安全的数据结构,例如集合、栈、队列和存储库,而不会丢失类型信息。



在本文中,我们将详细讨论 PHP 中的 Generics 是什么、为什么需要它们、如何在实际中正确使用它们,并查看具体的代码示例。



什么是 Generics,为什么需要它们?



Generics(泛型)是一种允许使用数据类型参数化类、接口、trait 和函数的机制。不必为每种类型编写单独的实现(例如 IntegerList、StringList、UserList),而是创建一个通用类 List<T>,其中 T 是具体类型的占位符,在使用时传入。



为什么需要它们?

  • 类型安全: IDE 和静态分析器(Psalm、PHPStan)可以检查集合中是否只包含一种类型的元素,从而在开发阶段防止错误。
  • 减少代码重复: 您无需为不同的数据类型编写相同的类。
  • 提高可读性: 代码变得自文档化——可以立即看到期望的数据类型。
  • 提高性能: 尽管 PHP 本身不像 Java 或 C# 那样在虚拟机级别使用 Generics,但静态分析器有助于在代码执行前发现潜在错误。


如何在 PHP 中使用 Generics?语法和示例



从 PHP 8.0 开始,在注解(docblock)级别以及部分在代码级别(对于可变参数)引入了对 Generics 的支持。完整的语法级别支持预计在未来版本中实现,但现在已经可以通过 PHPDoc 和静态分析器有效地使用 Generics。



1. 使用 PHPDoc 的基本语法



最常见的方法是使用 @template 和 @param/@return 注解,并指定泛型类型。



<?php

/** * @template T */class Collection { /** @var array<T> */ private array $items;

/** * @param T $item */ public function add($item): void { $this->items[] = $item; }

/** * @return T|null */ public function get(int $index) { return $this->items[$index] ?? null; }}

// 使用示例$intCollection = new Collection();$intCollection->add(42);// $intCollection->add('string'); // 静态分析器错误

$userCollection = new Collection();$userCollection->add(new User());// $userCollection->add(123); // 错误?>


在此示例中,@template T 声明了一个泛型类型。@param T $item 和 @return T|null 告诉分析器元素类型必须一致。



2. 类型约束(有界泛型)



您可以限制哪些类型可以用作参数。这通过 @extends 或 @implements 完成。



<?php

/** * @template T of \\Stringable */class StringableCollection { /** @var array<T> */ private array $items;

/** * @param T $item */ public function add($item): void { $this->it

博客

书籍推荐