PHP仍缺少位:泛型。

本文是有关PHP缺失位的系列文章的第一篇。
以后的文章将讨论其他类型的概念,例如访问器和数据类型。

PHP 7.2即将来临,带来了与类型相关的更改,例如签名中的object类型或参数类型扩展。
这些证实了PHP社区加强PHP类型系统并提高类型安全性的意愿。

在Libcast,我们赞赏这些更改,这些更改使您可以依靠IDE在键入时显示类型错误,并在编译时验证类型,从而减少了查找和修复错误所需的时间
我们希望泛型是一项功能,希望不久后可以使用PHP,并允许使用给定类型的泛型容器。

泛型

泛型类允许声明必须在使用时专用泛型容器 (您不能直接使用泛型类)。
任何类型都可以专用于泛型类,只要它们尊重泛型类中使用的签名即可。

泛型类可以使用几种泛型类型,然后仅通过修复泛型类型的子集来进行部分专业化

PHP中的泛型

RFC正在草拟中,但尚未被接受。

黑客/ HHVM 已经采用的泛型。

ircmaxellPHP用户环境中进行了一个有趣的实验(当然,请勿在产品中使用此功能)。

泛型在PHP中对于容器非常有用:抽象数据类型(堆栈,队列,地图等)和域容器(日期集,一组人等)。
它们还将允许更精确的签名:目前,PHP可以iterable地在签名中声明集合,但是通用声明iterable可以使我们仅要求书本集合。

Libcast的仿制药案例

我们创建了一个Libcast新安全视频平台API的模拟模型,在该模型中,我们需要随机生成数据,但有时需要遵循给定的分发方式。

例如,我们想要生成每个具有给定机会被发射的域事件,从而在模拟中生成真实的数据

我们还希望根据当前访客群的真实地理分布来模拟假访客。

我们看到了一个机会,可以根据普通类中的分布来提取做出选择的部分。

这是处理引用的示例的简化的第一枪:

  //生成IP地址 
 最终课程IpGenerator 
{
公共函数generate(string $ countryCode ='FR'):IP
{
// ...
}
}
 最后一个类DistributedIpGenerator 
{
/ ** @var IpGenerator * /
私人发电机
  / ** @var数组* / 
私人$发行;
 公共函数__construct(IpGenerator $ generator,数组$ distribution) 
{
$ this-> generator = $ generator;
$ this-> distribution = $ distribution;
}
 公共函数generate():IP 
{
//明智地选择国家代码
// $ countryCode = ...
 返回$ this-> generator-> generate($ countryCode); 
}
}
  //生成域事件 
 最后一课EventGenerator 
{
公共函数generate(string $ eventType):事件
{
}
}
 最后一个类DistributedEventGenerator 
{
/ ** @var EventGenerator * /
私人发电机
  / ** @var数组* / 
私人$发行;
 公共函数__construct(EventGenerator $ generator,array $ distribution) 
{
$ this-> generator = $ generator;
$ this-> distribution = $ distribution;
}
 公共函数generate():事件 
{
//明智地选择事件类型
// $ eventType = ...
 返回$ this-> generator-> generate($ eventType); 
}
}

除了签名返回类型DistributedIpGeneratorDistributedEventGenerator类几乎相同。
如果我们有泛型,则可以使用单个类:

 类DistributedGenerator  
{
/ ** @var可调用* /
私人发电机
  / ** @var数组* / 
私人$发行;
 公共功能__construct(可调用$ generator,数组$ distribution) 
{
$ this-> generator = $ generator;
$ this-> distribution = $ distribution;
}
 公共函数generate():DataType 
{
//明智地选择一个值
// $ value = ...
 返回$ this-> generator($ value); 
}
}

如果我们要生成给定类型的事件: UserEventVideoEvent ,…,则该泛型类可能会更加专门。
请注意,您还可以在通用类型列表中包括生成器类型,但是我们可能必须处理分布式生成器的几种实现:

 类DistributedGenerator  
{
/ ** @var GeneratorType * /
私人发电机
  / ** @var数组* / 
私人$发行;
 公共函数__construct(GeneratorType $ generator,array $ distribution) 
{
$ this-> generator = $ generator;
$ this-> distribution = $ distribution;
}
 公共函数generate():DataType 
{
//明智地选择一个值
// $ value = ...
  //这部分将针对每个GeneratorType进行更改: 
返回$ this-> generator-> whatever($ value);
}
}

泛型链接到各种类型的输入概念,我们可能会在其他文章中谈论其他类型。

参考文献

  • https://www.stitcher.io/blog/php-generics-and-why-we-need-them
  • https://wiki.php.net/rfc/generics
  • https://laracasts.com/discuss/channels/general-discussion/generics-equivalent-in-php
  • https://github.com/ircmaxell/PhpGenerics
  • https://github.com/TimeToogo/PHP-Generics
  • https://github.com/danielgsims/php-collections
  • https://wiki.php.net/rfc/arrayof