Hur de nya korsningstyperna i PHP 8.1 ger dig mer flexibilitet

0
175

Korsningstyper är en ny typ av systemfunktion som kommer i PHP 8.1. De låter dig skriva värden som måste uppfylla mer än en typbegränsning. PHP har redan fackliga typer som kombinerar typer med en logisk & # 8220; eller & # 8221; klausul; korsningstyper erbjuder en & # 8220; och & # 8221; i stället.

Vissa utvecklare skriver redan in korsningar med PHPDoc-anteckningar. Tillägget av inbyggt stöd är ett steg framåt eftersom typerna faktiskt kommer att tillämpas vid körning. De är också helt kompatibla med klassärv och hjälper till att minska risken för fel på grund av föråldrade eller inkompatibla anteckningar.

Basic Syntax

Korsningen typsyntax liknar unionstyper:

class DemoClass & # 123; & nbsp; offentligt Räknbart | Stringable $ Union; & nbsp; offentligt räknbart och strängbart $ skärningspunkt; & nbsp; & # 125;

I detta exempel kommer $ Union att tillgodoses av alla värden som är antingen räknbara eller strängbara. $ Intersection accepterar endast värden som uppfyller båda begränsningarna. Du får en TypeError om du tilldelar egenskapen ett värde som implementerar en eller noll av de antydda typerna.

Korsningstyper stöds överallt där typtips fungerar. Du kan använda dem med egendefinitioner, funktionsparametrar och returvärden.

Till skillnad från fackföreningstyper kan korsningar bara ange gränssnitt och klasser. En skalär korsning som int & amp; sträng är meningslös eftersom den aldrig kunde uppfyllas. Den blandade typen är också förbjuden, eftersom varje värde uppfyller dess begränsning.

Type Variance

Korsningstyper respekterar PHP: s befintliga variansregler. Returtyperna för åsidosatta metoder måste vara kovarianta, medan parametertyperna är kontravariant. Klassegenskaper är alltid oförändrade, så barn kan inte ändra typdefinitionen om inte den nya signaturen är både en undertyp och en supertyp av den ärvda.

Annons

För returvärden reglerar variansen menar att du kan lägga till ytterligare korsningstyper i åsidosatta metoder. Metoder kan också ta bort men inte lägga till korsningar som används som parametrar. Dessa regler verkställer Liskovs substitutionsprincip.

gränssnitt I1 & # 123; public function method1 & # 40; A & amp; B $ demo & # 41; : X & Y; public function method2 & # 40; A & amp; B $ demo & # 41; : X & Y; & # 125; & nbsp; gränssnitt I2 utökar I1 & # 123; & nbsp; //TILLÅTT allmän funktionsmetod1 & # 40; En $ demo & # 41; : X & amp; Y & amp; Z; & nbsp; //EJ TILLÅTT metod för offentlig funktion2 & # 40; A & amp; B & amp; C $ demo & # 41; : X; & nbsp; & # 125;

När det gäller metod 1 har begränsningarna inte förändrats. Du anger att den åsidosatta metoden faktiskt kan fungera med alla A, även om det inte också är ett X. Det är mindre specifikt vilket resulterar i acceptabel parametervarians. Returdeklarationen är mer specifik, där värdet kommer att implementera X, Y och Z; i det här scenariot bryter inte tillägget av kontraktet kontraktet, eftersom värdet fortfarande accepteras av allt som typtips I1.

Metod2-åsidosättningen bryts på båda punkterna. Genom att kräva att ingångsparametern uppfyller A, B och C är det inte längre en drop-in-ersättning för I1. På samma sätt garanterar metod2 endast att returvärdet kommer att vara en förekomst av X. Detta bryter kontraktet eftersom allt typtips I1 kräver värdet för att uppfylla korsningen mellan X och Y.

Korsningar inverterar de praktiska variansreglerna för fackliga typer. Eftersom fackföreningar kombineras med & # 8220; eller, & # 8221; barn kan lägga till parametertyper och ta bort returtyper. Liskov-substitutionsprincipen är uppfylld eftersom den utvidgande och minskande effekten av typbegränsningarna är omvänd.

Som med fackföreningstyper gäller variansregler också för de typer som utgör en korsning & # 8211; det är de enskilda X- och Y-delarna av X & Y. Du kan begränsa en typ när du returnerar den & # 8211; om att du kommer att returnera en underklass & # 8211; eller utvidga den som en parameter, acceptera en superklass.

Annons

Korsningar har också några speciella regler kring aliasing och konkreta implementeringar. Om du skriver tips X & amp; Y men skriver ett gränssnitt Z utökar X, Y, är det logiskt att Z uppfyller begränsningen. Följaktligen kan du skriva tips Z istället för X & amp; Y varhelst ko-varians är tillåten:

gränssnitt Test utvidgar X, Y & # 123; & # 125; & nbsp; gränssnitt Demo1 & # 123; offentlig funktionsdemo & # 40; & # 41; : X & Y; & # 125; & nbsp; gränssnitt Demo2 & # 123; offentlig funktionsdemo & # 40; & # 41; : Test; & # 125;

Det här låter dig skriva en konkret klass eller ett gränssnitt om du är beroende av ytterligare funktioner. Det är acceptabelt så länge alla begränsningar i korsningen är uppfyllda av den sista typtipsen.

När ska man använda korsningstyper?

Korsningstyper är för de tider då du vill vara säker på att ett värde uppfyller ett sammansatt gränssnitt utan att egentligen definiera det gränssnittet. Tidigare PHP-versioner gav inget stöd för detta, så du behövde lägga till en röra extra pannplatta i din kodbas:

gränssnitt CountableStringable utökas Countable, Stringable & # 123; //… & # 125; & nbsp; klass FakeArray implementerar CountableStringable & # 123; & nbsp; public array $ items = & # 91; & # 93 ;; & nbsp; antal offentliga funktioner & # 40; & # 41; : int & # 123; returräkning & # 40; $ detta – & gt; föremål & # 41 ;; & # 125; & nbsp; offentlig funktion __toString & # 40; & # 41; : sträng & # 123; returimplodera & # 40; & quot ;, & quot ;, $ detta – & gt; föremål & # 41 ;; & # 125; & nbsp; & # 125; & nbsp; klass DemoClass & # 123; & nbsp; public CountableStringable $ Value; & nbsp; & # 125;

Detta leder till ett överskott av stubbliknande grunda gränssnitt för att uppnå grundläggande korsningsbeteende. Även om PHP-utvecklare har överlevt utan korsningar hittills, hjälper deras närvaro att stärka typsystemets sammansatta funktioner. Genom att använda inbyggda korsningar skapas renare och mer intuitiv kod.

Vad sägs om komposit-typer?

Det är inte möjligt att kombinera korsning och unionstyper i samma typtips. Även om det skulle vara tekniskt möjligt har det utelämnats från den nuvarande RFC eftersom det finns tvetydigheter kring syntax, företräde och varians.

Sammansatta typer förblir en idé för framtiden. Om de lades till kan du börja lägga till komplexa typtips så här:

klass DemoClass & # 123; & nbsp; offentliga Räknbara & Stringable | CountableStringable $ skärningspunkt; & nbsp; & # 125; Annonsering

Denna exempelklass kombinerar de två implementeringarna från ovanstående. Om det fungerade skulle det låta dig anta infödda korsningstyper samtidigt som du behåller bakåtkompatibilitet med gamla klasser med hjälp av & # 8220; falska & # 8221; tillvägagångssätt.

Fullfjädrade komposittyper skulle avrunda den hantering av flera typer som underlättas av fackföreningar och korsningar. Under tiden måste du fortsätta skriva dina egna sammansatta gränssnitt i dessa scenarier.

Sammanfattning

Korsningstyper kommer till PHP 8.1 och kommer låsa upp mer avancerade möjligheter inom typsystemet. Genom att utvidga alternativen kring komposittyper minskas mängden kod du behöver skriva när flera gränssnitt stöds.

Korsningar är en valfri funktion som inte introducerar några inkompatibiliteter med befintlig kod. RFC implementerades i den tredje PHP 8.1 alfa-byggnaden. Den slutliga versionen kommer i slutet av november senare i år.