中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

不能在PHP中使用泛型的原因是什么

發布時間:2022-03-29 10:39:08 來源:億速云 閱讀:176 作者:小新 欄目:編程語言

小編給大家分享一下不能在PHP中使用泛型的原因是什么,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

為什么我們不能在 PHP 中使用泛型

我們將深入探討泛型和 PHP 背后的情況。理解為什么泛型在 PHP 中還不被支持作為一等公民,這非常有趣,并且非常重要。

不能在PHP中使用泛型的原因是什么

讓我們看看吧。

PHP 中沒有泛型。這就是去年的 Nikita 的結論。這根本不可行。

為了理解 Nikita 為什么這么說,我們需要看看如何實現泛型。一般來說,有三種可能的方法;支持泛型的編程語言大多使用這三種方法之一。

第一個稱為 單態泛型。 讓我們回到這個系列的第一篇文章,在這篇文章中我展示了這個集合示例:

class StringCollection extends Collection
{
    public function offsetGet(mixed $key): string 
    { /* … */ }
}
class UserCollection extends Collection
{
    public function offsetGet(mixed $key): User 
    { /* … */ }
}

我解釋了我們可以為需要的集合的每種類型,手動創建集合類的實現。 工作量將是巨大的,會有很多代碼,但是它會起作用。

單態泛型正是這樣做的,但在幕后自動實現。 在運行時,PHP 不會知道泛型 Collection 類,而是知道兩個或多個特定實現:

$users = new Collection<User>();
// Collection_User
$slugs = new Collection<string>();
// Collection_string

單態泛型是一種完全有效的方法。例如,Rust 就使用它們。 其一個優點是有一系列的性能提升,因為在運行時沒有更多的泛型類型檢查,所以在運行代碼之前,這些檢查都是分開的。

但是這立刻讓我們想到了 PHP 中單態泛型的問題。 PHP 沒有像 Rust 那樣將一個泛型類分成幾個具體實現的顯式編譯步驟;最重要的是:單態泛型確實需要相當多的內存,因為你在制作同一個類的多個副本,但有一些差異。 對于已編譯的 Rust 二進制文件來說,這可能不是一個大問題,但對于從中心點(服務器)運行的 PHP 代碼來說,這是一個嚴重的問題;可能每秒處理數百或數千個請求。

下一個選項是具體化泛型。這是一個實現,其中泛型類保持原樣,類型信息在運行時動態評估類型信息。C# 和 Kotlin 實現了泛型,它是最接近 PHP 當前類型系統的,因為 PHP 在運行時執行所有類型檢查。這里的問題是需要大量的核心代碼重構才能使具體化泛型發揮作用,你可以想象,隨著我們在運行時進行越來越多的類型檢查,一些性能開銷會逐漸增加。

這將我們帶到最后一個選項:在運行時完全忽略泛型。就像它們不在那里一樣;畢竟,例如集合類的泛型實現無論如何都可以處理所有類型的輸入。

因此,如果我們在運行時忽略所有泛型類型檢查,則不會有任何問題。

好吧,沒有那么快。 在運行時忽略泛型類型 —— 順便說一下,它被稱為類型擦除,Java 和 Python 會這樣做 —— 這給 PHP 帶來了一些問題。

舉一個例子:PHP 不僅使用類型進行驗證,它還使用類型信息將值從一種類型動態轉換為另一種類型 —— 這就是我在本系列的第一篇文章中提到的類型雜耍:

function add(int $a, int $b): int 
{
    return $a + $b;
}
add('1', '2') // 3;

如果 PHP 忽略了這個「字符串」集合的泛型類型,并且我們不小心向它添加了一個整數,那么如果泛型類型被刪除,它將無法警告我們:

$slugs = new Collection<string>();
$slugs[] = 1; // 1 不會被轉換為 '1'

類型擦除的第二個也是更重要的問題 —— 也許你現在已經在屏幕上大喊大叫了 —— 是類型消失了。如果泛型類型在運行時被刪除,我們為什么要添加它們?

這在 Java 和 Pyton 中是有意義的,因為在使用靜態分析器運行代碼之前會檢查所有類型定義。 例如,Java 在編譯代碼時會運行一個內置的靜態分析器; PHP 根本不會做的事情:沒有編譯步驟,當然也沒有內置的靜態類型檢查器。

另一方面…… 類型檢查的所有優點,我們在之前的文章中討論過的那些;它們不是來自 PHP 的內置運行時類型檢查器。當 PHP 的類型檢查器告訴我們有問題時,我們已經在運行代碼了。一個類型錯誤本質上是讓我們的程序崩潰。

相反,類型檢查的大部分附加值來自不需要我們運行代碼的靜態分析器。只要程序員提供足夠的類型信息,他們就能很好地確保不會出現運行時類型錯誤。這并不意味著你的代碼中不能有任何錯誤,但可以編寫完全靜態檢查并且在運行時不會產生任何類型錯誤的 PHP 代碼。最重要的是:我們在編寫代碼時獲得了所有靜態洞察;這是任何類型系統中最有價值的部分,與運行時類型檢查無關。

那么我們真的需要運行時類型檢查嗎?因為這是目前無法在 PHP 中添加泛型的主要原因:對于 PHP 來說,在運行時驗證泛型類型太復雜或太耗費資源。

以上是“不能在PHP中使用泛型的原因是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

叶城县| 古田县| 高雄县| 思茅市| 孝义市| 公主岭市| 沂源县| 芮城县| 城市| 寻乌县| 湖州市| 靖边县| 江门市| 鄂托克前旗| 漯河市| 璧山县| 巢湖市| 修文县| 白山市| 南丹县| 伊通| 营口市| 黄山市| 茶陵县| 云安县| 师宗县| 丁青县| 阜康市| 宜兰县| 锡林浩特市| 天津市| 滦南县| 山阳县| 瓮安县| 汕尾市| 建瓯市| 通渭县| 永安市| 卓尼县| 辉南县| 天峨县|