Pada artikel sebelumnya saya menulis tentang menambahkan enum di PHP8.1. Pemungutan suara berhasil, sehingga masalah bisa dipertimbangkan untuk diselesaikan.
Namun, implementasi enum tersebut hanyalah bagian dari rencana global . Hari ini kita akan mempertimbangkan item berikutnya, tagged union, dalam bahasa Rusia yang diterjemahkan sebagai "type-sum".
Ini belum dipilih , tetapi diusulkan untuk memasukkannya ke dalam PHP 8.1 juga.
Semua istilah "tipe data aljabar", "tipe-jumlah" ini terdengar menakutkan, tetapi pada kenyataannya semuanya cukup sederhana.
Mengapa semua ini perlu?
Hasil seperti di Rust
Jika Anda telah menulis di Rust, Anda mungkin telah menemukan Hasil enum bawaan. Di Rust, Go, dll. tidak ada mekanisme pengecualian, karena bahasa-bahasa ini menganggap penanganan kesalahan eksplisit jauh lebih dapat diandalkan. Bahasa tersebut memaksa Anda untuk secara eksplisit mengerjakan semua varian peristiwa, dan tidak membuat pengecualian dengan harapan seseorang di atas mengetahuinya dan tahu cara menanganinya dengan benar. (Jangan salahkan di sini, pada topik pengecualian vs jenis pengembalian, setiap orang memiliki pendapatnya sendiri). Berbicara secara khusus tentang Rust, hasil dari panggilan fungsi yang dapat menghasilkan kesalahan sering kali dijadikan nilai Hasil.
Hasil terdiri dari dua varian (kasus dalam terminologi enum PHP): Ok dan Err. Kita bisa membuat variasi menggunakan fungsionalitas enum sebelumnya, atau bahkan konstanta, tetapi kita juga perlu mengembalikan nilainya sendiri. Selain itu, jika berhasil, nilainya dapat berupa string, dan jika terjadi kesalahan, jenis lainnya. Misalnya, integer (status respons HTTP).
Bagaimana tampilannya di PHP jika pemungutan suara berhasil:
enum Result {
case Ok(public string $json);
case Err(public int $httpStatus);
}
function requestApi($url): Result {
//
}
sekarang kita dapat mentransfer jawaban ini ke tempat lain, dan pengetahuan tentang kesalahan dan jenisnya tidak akan pernah hilang.
Seperti yang saya tulis di artikel sebelumnya , enum pada dasarnya adalah kelas, dapat memiliki metode, dll. Dalam kasus tipe-jumlah, metode dapat berupa umum untuk seluruh enum atau untuk kasus tertentu.
Berikut contoh implementasi monad Maybe (contoh dari RFC):
The Maybe Monad
(Di Rust, tipe ini disebut Option)
enum Maybe {
// This is a Unit Case.
case None {
public function bind(callable $f)
{
return $this;
}
};
// This is a Tagged Case.
case Some(private mixed $value) {
// Note that the return type can be the Enum itself, thus restricting the return
// value to one of the enumerated types.
public function bind(callable $f): Maybe
{
// $f is supposed to return a Maybe itself.
return $f($this->value);
}
};
// This method is available on both None and Some.
public function value(): mixed {
if ($this instanceof None) {
throw new Exception();
}
return $this->val;
}
}
, : Some None, Some , None β None. bind. value()
RFC ,
$a = Maybe::Some("blabla");
// $a = Maybe::None
$a->bind();
, - Result Maybe , - . pattern matching, RFC, . , :
$result = requestApi($url);
if ($result is Result::Some {%$json}) {
// $json
}
if ($result is Result::Err {%$httpStatus}) {
// $httpStatus
}
, match.
, tagged unions. , - , , tokenizer (scanner), . : , enum. , , , . . :
enum Token {
case Comma;
case LeftBrace;
case RightBrace;
case StringLiteral(public string $str);
case Identifier(public string $identifier);
// ..
}
?
, RFC , , . , "" . tagged unions, , pattern matching.
Jika Anda tertarik dengan artikel serupa tentang pengembangan, khususnya, apa yang akan terjadi selanjutnya dengan pola pencocokan, berlangganan saluran telegram Cross Join !