一起来分析为什么不能在PHP中使用泛型

WBOY
Freigeben: 2023-04-10 22:38:01
nach vorne
5372 人浏览过

本篇文章给大家带来了关于PHP的相关知识,主要介绍了为什么不能在PHP中使用泛型,下面将深入探讨泛型和PHP背后的情况,理解为什么泛型还不被支持作为一等公民,希望对大家有帮助。

一起来分析为什么不能在PHP中使用泛型

推荐学习:《PHP教程

为什么我们不能在 PHP 中使用泛型

我们将深入探讨泛型和 PHP 背后的情况。理解为什么泛型在 PHP 中还不被支持作为一等公民,这非常有趣,并且非常重要。

一起来分析为什么不能在PHP中使用泛型

让我们看看吧。

PHP 中没有泛型。这就是去年的 Nikita 的结论。这根本不可行。

为了理解 Nikita 为什么这么说,我们需要看看如何实现泛型。一般来说,有三种可能的方法;支持泛型的编程语言大多使用这三种方法之一。

第一个称为 单态泛型。 让我们回到这个系列的第一篇文章,在这篇文章中我展示了这个集合示例:

class StringCollection extends Collection
{
    public function offsetGet(mixed $key): string 
    { /* … */ }
}
class UserCollection extends Collection
{
    public function offsetGet(mixed $key): User 
    { /* … */ }
}
Nach dem Login kopieren

我解释了我们可以为需要的集合的每种类型,手动创建集合类的实现。 工作量将是巨大的,会有很多代码,但是它会起作用。

单态泛型正是这样做的,但在幕后自动实现。 在运行时,PHP 不会知道泛型 Collection 类,而是知道两个或多个特定实现:

$users = new Collection();
// Collection_User
$slugs = new Collection();
// Collection_string
Nach dem Login kopieren

单态泛型是一种完全有效的方法。例如,Rust 就使用它们。 其一个优点是有一系列的性能提升,因为在运行时没有更多的泛型类型检查,所以在运行代码之前,这些检查都是分开的。

但是这立刻让我们想到了 PHP 中单态泛型的问题。 PHP 没有像 Rust 那样将一个泛型类分成几个具体实现的显式编译步骤;最重要的是:单态泛型确实需要相当多的内存,因为你在制作同一个类的多个副本,但有一些差异。 对于已编译的 Rust 二进制文件来说,这可能不是一个大问题,但对于从中心点(服务器)运行的 PHP 代码来说,这是一个严重的问题;可能每秒处理数百或数千个请求。

下一个选项是具体化泛型。这是一个实现,其中泛型类保持原样,类型信息在运行时动态评估类型信息。C# 和 Kotlin 实现了泛型,它是最接近 PHP 当前类型系统的,因为 PHP 在运行时执行所有类型检查。这里的问题是需要大量的核心代码重构才能使具体化泛型发挥作用,你可以想象,随着我们在运行时进行越来越多的类型检查,一些性能开销会逐渐增加。

这将我们带到最后一个选项:在运行时完全忽略泛型。就像它们不在那里一样;毕竟,例如集合类的泛型实现无论如何都可以处理所有类型的输入。

因此,如果我们在运行时忽略所有泛型类型检查,则不会有任何问题。

好吧,没有那么快。 在运行时忽略泛型类型 —— 顺便说一下,它被称为类型擦除,Java 和 Python 会这样做 —— 这给 PHP 带来了一些问题。

举一个例子:PHP 不仅使用类型进行验证,它还使用类型信息将值从一种类型动态转换为另一种类型 —— 这就是我在本系列的第一篇文章中提到的类型杂耍:

function add(int $a, int $b): int 
{
    return $a + $b;
}
add('1', '2') // 3;
Nach dem Login kopieren

如果 PHP 忽略了这个「字符串」集合的泛型类型,并且我们不小心向它添加了一个整数,那么如果泛型类型被删除,它将无法警告我们:

$slugs = new Collection();
$slugs[] = 1; // 1 不会被转换为 '1'
Nach dem Login kopieren

类型擦除的第二个也是更重要的问题 —— 也许你现在已经在屏幕上大喊大叫了 —— 是类型消失了。如果泛型类型在运行时被删除,我们为什么要添加它们?

这在 Java 和 Pyton 中是有意义的,因为在使用静态分析器运行代码之前会检查所有类型定义。 例如,Java 在编译代码时会运行一个内置的静态分析器; PHP 根本不会做的事情:没有编译步骤,当然也没有内置的静态类型检查器。

另一方面…… 类型检查的所有优点,我们在之前的文章中讨论过的那些;它们不是来自 PHP 的内置运行时类型检查器。当 PHP 的类型检查器告诉我们有问题时,我们已经在运行代码了。一个类型错误本质上是让我们的程序崩溃。

相反,类型检查的大部分附加值来自不需要我们运行代码的静态分析器。只要程序员提供足够的类型信息,他们就能很好地确保不会出现运行时类型错误。这并不意味着你的代码中不能有任何错误,但可以编写完全静态检查并且在运行时不会产生任何类型错误的 PHP 代码。最重要的是:我们在编写代码时获得了所有静态洞察;这是任何类型系统中最有价值的部分,与运行时类型检查无关。

那么我们真的需要运行时类型检查吗?因为这是目前无法在 PHP 中添加泛型的主要原因:对于 PHP 来说,在运行时验证泛型类型太复杂或太耗费资源。

原文地址:https://stitcher.io/blog/generics-in-php-3

译文地址:https://learnku.com/php/t/66486

推荐学习:《PHP视频教程

以上是一起来分析为什么不能在PHP中使用泛型的详细内容。更多信息请关注PHP中文网其他相关文章!

Verwandte Etiketten:
php
Quelle:learnku.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!