Operator trójargumentowy w Delphi
W PHP funkcjonuje coś takiego jak operator trójargumentowy. Jest to składnia języka, pozwalająca na zastąpienie pojedynczego bloku if…else w bardziej przejrzysty sposób:
warunek ? jeśli_prawda : jeśli_fałsz
Przykładowo:
$zmienna = $k >= 0 ? 'dodatnie' : 'ujemne';
…odpowiada konstrukcji:
if ($k >= 0)
{
$zmienna = 'dodatnie';
}
else
{
$zmienna = 'ujemne';
}
Jak widać uproszczenie jest znaczne. Object Pascal (Delphi) nie posiada niestety operatora trójargumentowego. W tym wpisie pokażę jak zastąpić tą funkcjonalność przy pomocy prostej funkcji i jej przeciążenia.
Zasadniczo, naszym zadaniem będzie stworzenie funkcji o 3 argumentach, która będzie odpowiednikiem operatora trójargumentowego. Jako iż nie jest to skomplikowane zadanie, przystąpmy do działania:
function IfThen(Condition: Boolean; const TrueValue: String; const FalseValue: String): String; begin if Condition then Result := TrueValue else Result := FalseValue; end;
Funkcję tę nazwałem IfThen, gdyż jest to w zasadzie skrót konstrukcji if…then…else. Pierwszym parametrem jest warunek, kolejnym zwracana wartość w przypadku spełnienia owego warunku i ostatnim, wartość w przypadku fałszu.
Jak możemy zauważyć, funkcja dedykowana jest jedynie dla argumentów będących ciągiem znaków. Korzystając z dyrektywy overload, stwórzmy przeciążone funkcje dostosowane do wielu różnych typów zmiennych. Całość, umieściłem od razu w osobnym module w celu łatwiejszego, późniejszego wykorzystania napisanych funkcji.
unit TripleOperator; interface function IfThen(Condition: Boolean; TrueValue, FalseValue: Byte): Byte; overload; function IfThen(Condition: Boolean; TrueValue, FalseValue: Integer): Integer; overload; function IfThen(Condition: Boolean; TrueValue, FalseValue: Single): Single; overload; function IfThen(Condition: Boolean; TrueValue, FalseValue: Double): Double; overload; function IfThen(Condition: Boolean; const TrueValue: String; const FalseValue: String): String; overload; implementation function IfThen(Condition: Boolean; TrueValue, FalseValue: Byte): Byte; begin if Condition then Result := TrueValue else Result := FalseValue; end; function IfThen(Condition: Boolean; TrueValue, FalseValue: Integer): Integer; begin if Condition then Result := TrueValue else Result := FalseValue; end; function IfThen(Condition: Boolean; TrueValue, FalseValue: Single): Single; begin if Condition then Result := TrueValue else Result := FalseValue; end; function IfThen(Condition: Boolean; TrueValue, FalseValue: Double): Double; begin if Condition then Result := TrueValue else Result := FalseValue; end; function IfThen(Condition: Boolean; const TrueValue: String; const FalseValue: String): String; begin if Condition then Result := TrueValue else Result := FalseValue; end; end.
Pobierz TripleOperator.pas.
Tym sposobem, zrealizowaliśmy operator trójargumentowy w Delphi dla kilku typów zmiennych. Jak widać, bardzo łatwo można dodać kolejne. Przykładowe użycie funkcji IfThen:
procedure TForm1.Button1Click(Sender: TObject); begin Caption := IfThen(Top <= 200, 'okno jest nisko', 'okno jest wysoko'); end;
Niestety są pewne kruczki w stosunku do wersji w PHP. Po pierwsze, jest to funkcja a nie składnia języka – ciut mniejsza wydajność. Po drugie, w przypadku spełnienia warunku, oba argumenty muszą zostać przekazane do funkcji, a nie tylko ten odpowiedzialny za prawdę. Innymi słowy, jeśli argumentami są wyniki działań innych funkcji, to bez względu na wynik parametru Condition, i tak obie zostaną wykonane, mimo że zwrócona zostanie tylko jedna z nich. Nie posiada tego mankamentu konstrukcja if…then…else, gdzie po wykonaniu pierwszej instrukcji, blok else w ogóle nie jest analizowany. W zależności od wykorzystania, może to nie mieć znaczenia lub mieć bardzo duże. Przykładowo:
Count := IfThen(i = 0, 8, 8 div i);
Taki przypadek, w sytuacji gdy zmienna i przyjmuje wartość 0, spowoduje niestety błąd.
Wszystko więc zależy od zastosowania, nie mniej, w większości przypadków skraca nam to ilość kodu jaki musielibyśmy napisać tradycyjnie.
Jeśli argumentami operatora ?: będą funkcje, to wykonana zostanie tylko jedna, przykładowo:
(3>3) ? foo() : bar();
, zaś w Twoim kodzie AFAIK zostaną wykonane obie:
IfThen(i3>3, foo(), bar());
.. co tu jest działaniem błędnym. Mam rację?
Masz rację, i napisałem dokładnie to samo pod koniec wpisu
No jest to wada tego rozwiązania, ale lepsze to niż nic – w prostych przypadkach poprawia znacznie przejrzystość kodu bo nie trzeba trzaskać if…else.
No racja, nie doczytałem, jeśli możesz wykasuj mój komentarz bo nic nie wnosi do tematu
Coś tam wnosi, Ci co nie doczytają dowiedzą się z komentarzy
Operator, o którym napisałeś pochodzi z C i został zapozyczony przez PHP
Żałuję że nie przez pozostałe języki również