<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 泛型 **泛型(Generics)** 是一種重要的編程范式,它允許程序員在編寫代碼時使用類型參數,這些類型參數在編譯時或運行時可以被具體的類型所替代。泛型的使用能夠增加代碼的復用性、靈活性和可維護性。使得這種數據類型能夠適用于不同的數據類型,從而實現代碼的復用和高效。 PHP是一種動態類型語言,不像C++、Java等語言有強類型機制,因此在PHP中實現泛型編程不是一件容易的事情。 ## PHP中的泛型 在PHP官方文檔中,并沒有直接提及`泛型`這個概念。這并不意味著PHP不支持泛型,而是說PHP沒有像Java或C#那樣顯式地提供泛型的語法支持。實際上這并不意味著PHP無法實現泛型的功能。 在PHP中,可以通過一些技巧和手段來模擬泛型的行為。例如可以使用接口(Interface)和類型提示(Type Hinting)來實現類似于泛型的功能。通過定義一個接口作為類型參數,我們可以實現類似泛型的類型檢查和類型約束。雖然這種方法與Java或C#中的泛型有所不同,但它確實提供了一種在PHP中實現泛型功能的方式。 一個簡單的例子 ```php <?php /** * @desc CollectionInterface * @author Tinywan(ShaoBo Wan) */ declare(strict_types=1); interface CollectionInterface { public function add($element); public function remove($element); public function contains($element): bool; public function size(): int; } class ArrayCollection implements CollectionInterface { private array $elements = []; public function add($element) { $this->elements[] = $element; } public function remove($element) { if (($key = array_search($element, $this->elements, true)) !== false) { unset($this->elements[$key]); } } public function contains($element): bool { return in_array($element, $this->elements, true); } public function size(): int { return count($this->elements); } } ``` 在上面例子中,使用了一個`CollectionInterface`接口來定義了一個通用的集合接口,然后實現了一個`ArrayCollection`類來實現`CollectionInterface`接口,這個類就可以用于操作任何類型的數據。 ## PHP為什么不支持泛型? 這可能與PHP的設計理念和歷史背景有關。**PHP是一種弱類型語言,它允許變量在運行時動態地改變類型。這種靈活性使得PHP在Web開發等領域具有廣泛的應用。實際上這種靈活性也帶來了一些問題,比如類型安全問題。泛型作為一種強類型特性,可以在一定程度上提高代碼的類型安全性。** 但是在PHP這種弱類型語言中引入泛型可能會與其設計理念產生沖突。 PHP最初是為了簡化Web開發而設計的,它的語法和功能都比較簡單和直接。隨著PHP的發展,雖然不斷有新的特性和語法被加入到PHP中,但PHP始終保持著一種簡潔和易用的風格。在這種背景下引入復雜的泛型語法可能會增加PHP的學習成本和開發難度。 ## PHP泛型即將來臨 ### 完全具體化的泛型 使用泛型,您可以使用占位符定義類的屬性和方法類型。然后可以在創建類的實例時指定這些。這使代碼可重用性和類型安全跨不同的數據類型。`具體化`的泛型是定義泛型類型信息并將其延續到運行時的實現,允許在運行時強制執行泛型需求。 作為PHP語法,這可能看起來像這樣 ```php class Entry<KeyType, ValueType> { public function __construct(protected KeyType $key, protected ValueType $value) { } public function getKey(): KeyType { return $this->key; } public function getValue(): ValueType { return $this->value; } } new Entry<int, BlogPost>("123", new BlogPost()); ``` 在實例化的類中,泛型類型`KeyType`將被替換為`int`,`ValueType`的每個實例將被替換為`BlogPost`,從而導致對象的行為類似于以下類定義: ```php class IntBlogPostEntry { public function __construct(protected int $key, protected BlogPost $value) { } public function getKey(): int { return $this->key; } public function getValue(): BlogPost { return $this->value; } } ``` 泛型的使用往往會增加代碼的冗長性,因為它要求每次引用泛型類型時都指定類型參數。這在下面的PHP代碼片段中得到了演示: ```php function f(List<Entry<int,BlogPost>> $entries): Map<int, BlogPost> { return new Map<int, BlogPost>($entries); } function g(List<BlogPostId> $ids): List<BlogPost> { return map<int, BlogPostId, BlogPost>($ids, $repository->find(...)); } ``` 類型推斷可以通過讓編譯器自動為我們推斷適當的類型來減少這種冗長。例如,在上面的示例中,編譯器可能會自動確定`new Map()`和`map()`的正確類型。但是,這在PHP中很難實現。引用`Nikita`的話:`主要是由于PHP編譯器對代碼庫的視圖非常有限(它一次只能看到一個文件)`。 請看下面的例子 ```php class Box<T> { public function __construct(public T $value) {} } new Box(getValue()); ``` 在這種情況下,`getValue()`表達式的類型是未知的,直到函數在運行時加載,使得無法推斷`new Box(.)`中的`T`。在編譯期間。 我們可以在運行時根據函數的返回值分配T,但這會導致類型不穩定。在前面的例子中,`new Box()`的類型將取決于`getValue()`的返回值的實現,這可能太具體了:聯合收割機結合`Box`是不變的這一事實,當試圖對Box實例做任何有用的事情時,這段代碼將很快中斷: ```php interface ValueInterface {} class A implements ValueInterface {} class B implements ValueInterface {} function getValue(): ValueInterface { return new A(); } function doSomething(Box<ValueInterface> $box) { } $box = new Box(getValue()) // runtime: Box<A>, statically: Box<ValueInterface> doSomething($box); // accepts Box<ValueInterface>, not Box<A> ``` 當類型基于不依賴于實現的編譯時/靜態信息時,類型是最有用的。 注意:在這個例子中,`Box`是不變的,因為它通常是泛型類的情況。這意味著無論X和Y之間的關系如何,`Box<X>`都不是`Box<Y>`的子類型或超類型,因此Box<A>不是`Box<ValueInterface>`的子類型,并且`doSomething()`不能接受`Box<A>`。 ## 集合 泛型的一個主要用例是需要類型化數組。在PHP中,瑞士軍刀數組類型的使用(和濫用)有很多原因。但是你目前不能強制將類型用作鍵或值。 在一個并行項目中,我們一直在研究一種專用的Collections語法,作為完整泛型的一種挑戰性較小的替代方案。 集合有三種形式:集合、序列和字典。集合和序列只定義一個值類型,而字典有鍵和值類型。其語法可以如下所示: ``` class Article { public function __construct(public string $subject) {} } collection(Seq) Articles<Article> { } collection(Dict) YearBooks<int => Book> { } ``` 然后你可以像對普通類一樣實例化序列和集合: ``` $a1 = new Articles(); $b1 = new YearBooks(); ``` Sequences和Dictionaries將自動[定義許多方法](https://github.com/php/php-src/compare/master...derickr:php-src:collections#diff-eeb1e0848e9a25b7492398bf5ddf9be15995a67d44a23c336869bf9f36910d1b),提供類似PHP已經擁有的大量`array_*`函數的基本功能。如果使用定義的方法來添加或更新集合中的元素,則鍵和值的類型必須與集合中定義的類型相匹配。 在上面的例子中,YearBooks字典的`add()`方法要求使用int作為鍵,Book作為值。對于主要的操作方法(add、get、unset和isset),ArrayAccess風格的重載操作也可以工作,以及潛在的操作符重載。 集合的一個缺點是你需要聲明它們。按照已采用的做法,這意味著每個集合在單獨的文件中有一行聲明。 另一個問題是潛在的更高的內存使用,因為對于每個類,PHP必須保留一個相應的類條目,包括所有相關方法的列表。 第三個問題是兼容類型的集合之間沒有instanceof/is-a關系,例如: ``` class A {} class B extends A {} seq As<A> {} seq Bs<B> {} new B() instanceof A // true new Bs() instanceof As // false ``` 集合雖然功能不太強大,但在許多用例中可以替代泛型,但沒有太多的復雜性。上面概述的實現也明顯更容易。[還提供了](https://github.com/derickr/php-src/tree/collections)一個實驗性分支。然而,如果發現完整的泛型是可行的并且得到支持,那么直接在標準泛型上實現Seq、Set和Dict將是非常可取的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看