CakeFest 2024: The Official CakePHP Conference

Warum Enums nicht erweiterbar sind

Klassen haben Vereinbarungen bezüglich ihrer Methoden:

<?php

class A {}
class
B extends A {}

function
foo(A $a) {}

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

Dieser Code ist typsicher, da B der Vereinbarung von A folgt, und die Magie der Ko-/Kontra-Varianz sicherstellt, dass bis auf Exceptions alle an die Methoden gestellten Erwartungen erfüllt werden.

Enums haben Vereinbarungen über ihre Fälle, nicht über ihre Methoden:

<?php

enum ErrorCode {
case
SOMETHING_BROKE;
}

function
quux(ErrorCode $errorCode)
{
// Mit diesem Code werden offenbar alle Fälle abgedeckt
match ($errorCode) {
ErrorCode::SOMETHING_BROKE => true,
}
}

?>

Die Anweisung match in der Funktion quux kann statisch analysiert werden, um alle Fälle in ErrorCode abzudecken.

Aber angenommen, es wäre erlaubt, Enums zu erweitern:

<?php

// Ein gedankliches Code-Experiment, bei dem Enums nicht final sind.
// Es ist zu beachten, dass dies in PHP nicht funktioniert.
enum MoreErrorCode extends ErrorCode {
case
PEBKAC;
}

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

fot(MoreErrorCode::PEBKAC);

?>

Nach den normalen Vererbungsregeln besteht eine Klasse, die eine andere Klasse erweitert, die Typprüfung.

Das Problem besteht darin, dass die Anweisung match in quux() nicht mehr alle Fälle abdeckt. Da sie MoreErrorCode::PEBKAC nicht kennt, löst der Abgleich eine Exception aus.

Aus diesem Grund sind Enums final und können nicht erweitert werden.

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top