Drukowana wersja tematu

Kliknij tu, aby zobaczyć temat w orginalnym formacie

Forum PHP.pl _ Newsy _ PHP8 nowa instrukcja warunkowa match

Napisany przez: Tomplus 5.08.2020, 10:03:49

Od wersji PHP 8 otrzymamy nową instrukcję warunkową match. Będzie to świetna funkcja, która będzie częstszym wyborem do korzystania niż switch. Spójrzmy na różnice.

Klasyczna instrukcja http://php.net/switch, plaintext

  1. switch ($statusCode) {
  2. case 200:
  3. case 300:
  4. $message = null;
  5. break;
  6. case 400:
  7. $message = 'not found';
  8. break;
  9. case 500:
  10. $message = 'server error';
  11. break;
  12. default:
  13. $message = 'unknown status code';
  14. break;
  15. }
[PHP] pobierz, plaintext


Nowa instrukcja http://php.net/match, plaintext
  1. $message = match ($statusCode) {
  2. 200, 300 => null,
  3. 400 => 'not found',
  4. 500 => 'server error',
  5. default => 'unknown status code',
  6. };
[PHP] pobierz, plaintext


Podsumowując http://php.net/match;
- nie wymaga używania http://php.net/break, plaintext
  1. $statusCode = '200';
  2.  
  3. $message = match ($statusCode) {
  4. 200 => null,
  5. default => 'unknown status code',
  6. };
  7.  
  8. // $message = 'unknown status code'
[PHP] pobierz, plaintext



Brak wartości w instrukcji match zwraca błąd
Jeżeli instrikcja http://php.net/match, plaintext
  1. $statusCode = 400;
  2.  
  3. $message = match ($statusCode) {
  4. 200 => 'perfect',
  5. };
  6.  
  7. // UnhandledMatchError


### Łączenie warunków
Już powyższych przykładach można było zobaczyć połączone warunki, oddzielone jedynie przecinkami, coś podobnego jak przy http://php.net/switch, plaintext
  1. switch ($statusCode) {
  2. case 200:
  3. case 300:
  4. case 400:
  5. $message = 'combined expressions';
  6. break;
  7. }


Przy match okazuje się to prostsze, z mniejszą ilością pisania i mniej możliwości na błędy.


  1. $message = match ($statusCode) {
  2. 200, 300, 301, 302 => 'combined expressions',
  3. };


### Złożone warunki i wydajność
Możliwość użycia wyrażeń regularnych podczas dopasowania może być bardzo użyteczny przy wielu podobnych wartościach warunkowych, ale należy pamiętać że płynie to na spadek wydajności aplikacji, jednakże użyteczność tego wzorca dodatkowo pozytywnie odbije się na częstotliwości użycia nowej instrukcji.

  1. $message = [
  2. $this->matchesRegex($line) => 'match A',
  3. $this->matchesOtherRegex($line) => 'match B',
  4. ][$line] ?? 'no match';


### Rzucanie wyjątków
Rzucanie wyjątków throw w PHP 8, wtedy gdy potrzebujesz tak jak na przykładzie poniżej:

  1. $message = match ($statusCode) {
  2. 200 => null,
  3. 500 => throw new ServerError(),
  4. default => 'unknown status code',
  5. };


### Dopasowanie wzorców
Jedna z technik używana w innych językach programowania, umożliwiająca bardziej złożone dopasowywanie niż proste wartości. Coś jak wyrażenie regularne, ale o zmiennych zamiast treści. Jest to dopiero funkcja przyszłości która bo jest to na tyle złożony temat, że aby dobrze działała potrzeba poświęcić trochę więcej czasu nad nią.

### Na razie tylko wyrażenia jednowierszowe
Łyżka dziegciu do miodu musi być, a tym jest że wyrażenia mogą być tylko jednowierszowe. Tworzenie całych bloków wyrażeń, tak jak w http://php.net/switch

Napisany przez: nospor 5.08.2020, 10:55:08

Hm, ciekawie wyglada. Dzieki za info smile.gif

Napisany przez: SmokAnalog 7.08.2020, 13:18:37

Coś podobnego (ale dużo bardziej zaawansowanego) jest w Swifcie (jako część specyfikacji switch). Języki w ogóle się do siebie coraz bardziej upodabniają.

W Swifcie też dobrze wymyślili, że switch domyślnie nie przechodzi do kolejnej opcji. W sumie to jak się zastanowić, zachowanie switch znane z PHP i wielu innych językach C-podobnych jest absurdalne. Dużo częściej wstawia się break niż korzysta z domyślnego zachowania, czyli jest to kiepski pomysł. W Swifcie zamiast tego jest słowo "fallthrough", które włącza zachowanie znane z C:

Kod
var zwierze = "Tygrys"

switch zwierze {
   case "Tygrys", "Lew":
      print("Jestem tygrysem lub lwem")
      fallthrough
   case "Kot":
      print("Jestem kotem")
   case "Pies" :
      print("Jestem psem")
   default :
      print("Nie wiadomo kim jestem")
}


I tak, wartość Tygrys i Kot wypiszą zarówno "Jestem tygrysem lub lwem" i "Jestem kotem". Ma to o wiele więcej sensu niż wymaganie break wszędzie tam, gdzie nie chcemy iść dalej.

Napisany przez: Szado 15.08.2020, 13:37:55

Małe, a cieszy.

Napisany przez: SmokAnalog 16.08.2020, 08:16:30

Cytat(Szado @ 15.08.2020, 14:37:55 ) *
Małe, a cieszy.

That's what she said.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)