透過範例來深入了解PHP中的泛型
這篇文章帶大家深入了解PHP中的泛型,介紹兩個泛型範例,希望對大家有幫助!
深入泛型
#我在上一篇 中展示了一個非常無聊的泛型示例,我們將在這個中做得更好。
$users = new Collection<User>(); $slugs = new Collection<string>();
集合
它們可能是解釋泛型的最簡單方法,但它們也是每個人在討論泛型時都會談論的範例。人們通常認為「泛型」和「具有類型的集合」是一回事。絕對不是這樣。
所以讓我們再看兩個例子。
這是一個名為「app」的函數-如果你使用像Laravel 這樣的框架,它可能看起來很熟悉:這個函數接受一個類別名,並且使用依賴容器解析該類別的一個實例:
function app(string $className): mixed { return Container::get($className); }
現在,你不需要知道容器是如何運作的,重要的是這個函數會給你一個你要求的類別的實例。
所以,基本上,它是一個通用函數;一個回傳類型取決於你給它的類別名稱。如果我們的IDE 和其他靜態分析器也明白,如果我給這個函數提供類別名稱“UserRepository”,我希望回傳一個UserRepository 的實例,而不是別的,那就太酷了:
function app(string $className): mixed { /* … */ } app(UserRepository::class); // ?
好吧,泛型允許我們這樣做。
我想現在是提一下我一直保守秘密的好時機,就像: 我在 上一篇 中提到 PHP 中不存在泛型;好吧,這並不完全正確。那裡的所有靜態分析器——無需運行即可讀取程式碼的工具,像你的IDE 之類的工具——他們允許將doc 塊註釋用於泛型:
/** * @template Type * @param class-string<Type> $className * @return Type */ function app(string $className): mixed { /* … */ }
誠然:這不是最完美的語法,所有靜態分析器都依賴於一個簡單的協議,即這是沒有官方規範語法; 但是:它有效。 PHP 世界中最大的三個靜態分析器:PhpStorm、Psalm 和 PhpStan,都在某種程度上理解這種語法。
像PhpStorm 這樣的IDE 使用它,以便在程式設計師編寫程式碼時向他們提供回饋,而像Psalm 和PhpStan 這樣的工具使用它,來批次分析你的程式碼庫並偵測潛在的bug,主要基於類型定義。
所以實際上,我們可以建立這個 app
函數,使我們的工具不再在黑暗中運作。當然,PHP 本身並不能保證返回類型是正確的,因為PHP 不會在運行時對該函數進行類型檢查; 但是,如果我們可以相信我們的靜態分析器是正確的,那麼在運行它時,這段程式碼就很少——甚至沒有機會被中斷。
這就是靜態分析令人難以置信的力量:實際上,我們可以確定,無需運行我們的程式碼; 其中大部分將按預期工作。所有這一切都歸功於類型——包括泛型。
讓我們來看一個更複雜的範例:
Attributes::in(MyController::class) ->filter(RouteAttribute::class) ->newInstance() ->
在這裡,我們有一個可以「查詢」屬性並即時實例化它們的類別。如果你在知道它們的反射 API 相當冗長之前使用過屬性,那麼我發現這種輔助類別非常有用。
當我們使用filter
方法時,我們給它一個屬性的類別名稱; 然後呼叫newInstance
方法,我們知道結果將是我們過濾類別的實例。再說一次:如果我們的 IDE 能理解我們在說什麼,那就太好了。
你猜對了:泛型允許我們這樣做:
/** @template AttributeType */ class Attributes { /** * @template InputType * @param class-string<InputType> $className * @return self<InputType> */ public function filter(string $className): self { /* … */ } /** * @return AttributeType */ public function newInstance(): mixed { /* … */ } // … }
我希望你開始看到簡單類型資訊的強大功能。幾年前,我需要一個 IDE 插件才能讓這些洞察力發揮作用,現在我只需要添加一些類型資訊。
不過,這個最新的範例不僅依賴泛型,還有另一個同樣重要的部分在運作。類型推斷:靜態分析器「猜測」—— 或可靠地確定 —— 無需使用者指定類型的能力。這就是那裡的類別字串註解正在發生的事情。我們的 IDE 能夠將我們提供給此函數的輸入識別為類別名,並將該類型推斷為泛型類型。
所以,一切都解決了,對吧:PHP中有泛型,所有主要的靜態分析器都知道如何使用它們。嗯…有幾個警告。
首先,沒有關於泛型應該是什麼樣子的官方規範,現在每個靜態分析器都可以使用自己的語法;目前,他們碰巧已經就其中一個達成了一致;但未來幾乎沒有保障。
其次:在我看來,文檔區塊是次優的。他們覺得自己在我們的程式碼庫中不那麼重要。當然,泛型註解只提供靜態洞察,沒有執行時間功能,但我們已經看到了靜態分析的強大功能,即使沒有執行時間類型檢查。我認為將類型資訊視為“文檔註釋”是不公平的,它沒有在我們的程式碼中傳達這些類型的重要性。這就是為什麼我們在PHP8中得到了屬性:屬性提供的所有功能,在docblock註解中都是可能的,但感覺還不夠好。泛型也是如此。
最後一點:如果沒有合適的規範,所有三種主要的靜態分析儀在其泛型實作之間都存在差異。 PhpStorm是目前最缺乏的一種。理想情況下,會有一個來自PHP內部的官方規範。但是官方現在沒有。
這些是我認為值得在更持久、更永續的解決方案上投入時間的主要原因。那為什麼PHP還沒有合適的泛型呢?為什麼我們依賴沒有明確規範的文檔區塊?
原文網址:https://stitcher.io/blog/generics-in-php-2
翻譯網址:https://learnku.com/php/t/ 66484
推薦:《PHP影片教學》
以上是透過範例來深入了解PHP中的泛型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。
