PHP8 為什么枚舉不可擴展

2023-08-19 16:08 更新

類在方法有契約:

<?php

class A {}
class B extends A {}

function foo(A $a) {}

function bar(B $b) {
foo($b);
}
?>

這段代碼類型安全,因為 B 遵循 A 的契約,并通過協(xié)變/逆變的邏輯,將會保留任何對方法的期望,除了異常。

枚舉在其選項上有契約,而不是方法:

<?php
enum ErrorCode {
case SOMETHING_BROKE;
}

function quux(ErrorCode $errorCode)
{
// When written, this code appears to cover all cases
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
}
}

?>

在函數(shù) quux 中,match 語句可以進行靜態(tài)分析,以涵蓋 ErrorCode 中的所有情況。

但是想一下,如果允許擴展枚舉:

<?php
// Thought experiment code where enums are not final.
// Note, this won't actually work in PHP.
enum MoreErrorCode extends ErrorCode {
case PEBKAC;
}

function fot(MoreErrorCode $errorCode) {
quux($errorCode);
}

fot(MoreErrorCode::PEBKAC);

?>

根據(jù)正常的繼承規(guī)則,繼承另一個類的類將通過類型檢查。

問題在于 quux() 中的 match 語句不再涵蓋所有情況。因為它不知道 MoreErrorCode::PEBKAC,所以匹配語句會拋出異常。

因此,枚舉是 final,不能擴展。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號