PHP重新构想
这篇文章是讲我们如何来改变 PHP, 使它变得更好。这是一个非常主观的清单, 绝不是对核心团队正在做的工作的批评。
类默认为final
对 面向对象 编程的一个常见误解是, 基本都是关于继承的。继承和多态性有它们自己的位置, 但面向对象 远不止这些。
因为这些原则往往被程序员滥用, 他们声称他们写的是"面向对象"的 代码, 我认为语言应该有助于防止我们犯这些错误。
这就是为什么我会使所有类在默认情况下都是final的:
final class Foo
{
}
class Bar extends Foo
{
}
此外: 类只允许从抽象类继承或实现接口。这样我们就可以防止具体类的深度继承链。
返回类型默认为Void
Void在所有编程语言中都是如此奇怪:它是一种“类型”,表明缺少类型。
为什么不采用明显的方式:没有返回类型,意味着什么也没有返回。
class Foo
{
public function bar(): void
{
// …
}
}
class Foo
{
public function bar()
{
return false;
}
}
现在你可能会想:如果函数想要返回两种类型,那就是下一点。
禁止mixed类型
mixed
类型基本上意味着:“你不知道这个功能需要或将返回什么,得自己弄清楚”。
这种松散类型的系统可能是许多错误的根源。如果你觉得需要在同一个函数中使用两种不同的类型,你应该用两个实现 - 这是多态性应该做的; 或者你应该编程到一个接口。
无论哪种方式,总有一个更好的解决方案,然后依靠mixed
。在我的PHP版本中,语言将确保我们始终选择更好的解决方案。
禁止方法重载
这是PHP的的一个常见功能请求:对同一方法有多个定义。我反对它的论点与前一个论点直接相关:有一个更好的解决方案来解决这个问题。
如果您觉得需要一个具有两个实现的方法,您应该查看接口的多态或编程到接口。
class Foo
{
public function handle(Bar $bar) { /* … */ }
public function handle(Foo $bar) { /* … */ }
}
所有参数都必须类型化
我们已经确定我的PHP版本会生成所需的返回类型。毫无疑问,函数参数也是如此
public function handle($bar)
{
}
public function handle(Bar $bar)
{
}
类属性必须具有类型
相同的规则适用于类属性。幸运的是,PHP 7.4将引入类型属性。
class Foo
{
public $bar;
}
class Foo
{
public Bar $bar;
}
可见性修饰符是必需的
明确性消除了混淆的空间。这就是为什么所有方法和类变量都必须具有可见性修饰符的原因。
class Foo
{
function bar()
{
// …
}
}
class Foo
{
public function bar()
{
// …
}
}
final变量
我说我会放弃final关键字, 在类和方法上。final将是一个合法的关键字, 将类变量标记为 "只读"。
final变量可以在构造上设置, 之后不能更改。
class Foo
{
public final Bar $bar;
public __construct(Bar $bar)
{
$this->bar = $bar;
}
}
$foo = new Foo($bar);
$foo->bar = new Bar();
标量类型也是对象
我认为我们都同意的为数不多的一点是: 目前的 PHP 函数名称和定义不一致, 有点糟糕。。
让我们将所有标量类型视为对象,允许它们包含什么否则将是独立函数。
public function handle(): String
{
return "a, b, c";
}
$this->handle()->explode(',');
改善类型协变
您可能已经注意到上述变化的趋势。其中大多数与PHP的类型系统有关。如果添加了所有这些,我们还需要使当前类型系统更加灵活。
幸运的是,PHP 7.4已经引入了关于类型协变的改进。
class Bar extends Foo { /* … */ }
interface A
{
public function handle(Bar $bar): Foo;
}
class B implements A
{
public function handle(Foo $bar): Bar
{
// …
}
}
始终严格的类型检查
默认情况下会进行严格的类型检查,您永远不应该declare(strict_types=1);再进行。
泛型
在对类型系统进行了几次改进之后,我会添加一些更实用的方法。
首先,可能是大多数PHP世界都在等待的功能:泛型。
class List<T>
{
public function current(): T
{
// …
}
}
枚举类型
接下来:内置枚举。基于几个 用户区 实现 ,很明显社区将受益于内置的枚举类型。
enum Status
{
DRAFT, STATUS, PUBLISHED;
}
class Bar
{
public Status $status;
}
$bar->status = Status::DRAFT;
Structs结构体
结束此列表:结构。我一直使用的自己的一个包是data transer对象包。它允许定义强类型对象。从本质上讲,它们是结构体要解决的用户态实现。
struct Point {
Int $x;
Int $y;
}
$point = Point {1, 2}
这是Java!
这是我听到PHP程序员经常在提出对类型系统的改进时所说的话。请记住,编程语言不仅仅是它的语法:有一个完整的框架和包生态系统,它为PHP这样的语言提供了真正的价值。
参考 https://stitcher.io/blog/php-reimagined
原创翻译,转载请注明来自Lenix的博客,地址http://blog.p2hp.com/archives/5959