PHP仍缺少位:泛型。
本文是有关PHP缺失位的系列文章的第一篇。
以后的文章将讨论其他类型的概念,例如访问器和数据类型。
PHP 7.2即将来临,带来了与类型相关的更改,例如签名中的object
类型或参数类型扩展。
这些证实了PHP社区加强PHP类型系统并提高类型安全性的意愿。
在Libcast,我们赞赏这些更改,这些更改使您可以依靠IDE在键入时显示类型错误,并在编译时验证类型,从而减少了查找和修复错误所需的时间 。
我们希望泛型是一项功能,希望不久后可以使用PHP,并允许使用给定类型的泛型容器。
泛型
泛型类允许声明必须在使用时专用的泛型容器 (您不能直接使用泛型类)。
任何类型都可以专用于泛型类,只要它们尊重泛型类中使用的签名即可。
泛型类可以使用几种泛型类型,然后仅通过修复泛型类型的子集来进行部分专业化 。
PHP中的泛型
RFC正在草拟中,但尚未被接受。
黑客/ HHVM 已经采用的泛型。
ircmaxell在PHP用户环境中进行了一个有趣的实验(当然,请勿在产品中使用此功能)。
泛型在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);
}
}
除了签名和返回类型 , DistributedIpGenerator
和DistributedEventGenerator
类几乎相同。
如果我们有泛型,则可以使用单个类:
类DistributedGenerator
{
/ ** @var可调用* /
私人发电机
/ ** @var数组* /
私人$发行;
公共功能__construct(可调用$ generator,数组$ distribution)
{
$ this-> generator = $ generator;
$ this-> distribution = $ distribution;
}
公共函数generate():DataType
{
//明智地选择一个值
// $ value = ...
返回$ this-> generator($ value);
}
}
如果我们要生成给定类型的事件: UserEvent
, VideoEvent
,…,则该泛型类可能会更加专门。
请注意,您还可以在通用类型列表中包括生成器类型,但是我们可能必须处理分布式生成器的几种实现:
类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