Varför uppräkningar inte är utbyggbara

Från Wiki.linux.se
Version från den 13 oktober 2024 kl. 13.03 av Admin (diskussion | bidrag) (→‎Varför enums inte kan utökas)
(skillnad) ← Äldre version | Nuvarande version (skillnad) | Nyare version → (skillnad)
Hoppa till navigering Hoppa till sök


Klasser har kontrakt på sina metoder:

class A {}
class B extends A {}

function foo(A $a) {}

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

Denna kod är typ-säker, eftersom B följer kontraktet för A, och genom co/contra-variansens magi kommer alla förväntningar man kan ha på metoderna att bevaras, med undantag för undantag.

Enums har kontrakt på sina cases, inte metoder:

enum ErrorCode {
    case SOMETHING_BROKE;
}

function quux(ErrorCode $errorCode)
{
    // När det skrivs, verkar denna kod täcka alla fall
    match ($errorCode) {
        ErrorCode::SOMETHING_BROKE => true,
    }
}

Match-satsen i funktionen quux kan statiskt analyseras för att täcka alla fall i ErrorCode.

Men tänk om det var tillåtet att utöka enums:

/* Tankeexperiment där enums inte är slutgiltiga.
   Observera, detta kommer faktiskt inte att fungera i PHP. */
enum MoreErrorCode extends ErrorCode {
    case PEBKAC;
}

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

fot(MoreErrorCode::PEBKAC);

Under normala arvregler skulle en klass som utökar en annan klara typkontrollen.

Problemet skulle vara att match-satsen i quux() inte längre täcker alla fall. Eftersom den inte känner till MoreErrorCode::PEBKAC kommer match-satsen att kasta ett undantag.

På grund av detta är enums slutgiltiga och kan inte utökas.

Sidslut

Orginalhemsidan på Engelska : https://www.php.net/manual/en/language.enumerations.object-differences.inheritance.php
PHP
Språkreferens
Språkreferens#Uppräkningar


Det här är en maskinöversättning av PHP-manualen till svenska. Om du hittar fel är vi tacksamma om du rapporterar dem via formuläret som finns på https://www.linux.se/kontaka-linux-se/