Operator wyboru w Delphi
Patryk27
Jak wszyscy wiedzą, w Pascalu nie istnieje C++'owski operator wyboru (conditional operator
):
warunek?wartość_true:wartość_false
i co najwyżej można użyć ifthen
oraz tym podobnych funkcji.
Postanowiłem więc trochę pokombinować i napisałem taki kod (dla FPC>=2.6; w nowszych Delphi także powinien działać):
{$MODE DELPHI}
Type TLazy<T> = Record
Type TFunc = Function: T;
Class Function Lazy(aCondition: Boolean; aTrue, aFalse: T): T; static;
Class Function LazyFunc(aCondition: Boolean; aTrue, aFalse: TFunc): T; static;
End;
Class Function TLazy<T>.Lazy(aCondition: Boolean; aTrue, aFalse: T): T;
Begin
if (aCondition) Then
Result := aTrue Else
Result := aFalse;
End;
Class Function TLazy<T>.LazyFunc(aCondition: Boolean; aTrue, aFalse: TFunc): T;
Begin
if (aCondition) Then
Result := aTrue() Else
Result := aFalse();
End;
Function Val1: Integer;
Begin
Writeln('Val1');
Result := 10;
End;
Function Val2: Integer;
Begin
Writeln('Val2');
Result := 20;
End;
Begin
Writeln(TLazy<Integer>.LazyFunc(False, Val1, Val2));
ReadLn;
End.
Kod zwróci:
Val2
20
Istnieją dwa typy jego wywołań:
TLazy<nazwa typu>.Lazy(warunek, wartość dla true, wartość dla false)
oraz
TLazy<nazwa typu>.LazyFunc(warunek, funkcja dla true, funkcja dla false)
Różnica jest taka, iż w przypadku użycia pierwszej opcji (Lazy
), obliczona zostanie wartość funkcji (czyli nota bene funkcja zostanie wywołana wtedy, gdy nie będzie ona potencjalnie potrzebna), podczas gdy używając drugiej (LazyFunc
), wywoływana jest tylko jedna, wymagana funkcja.
Korzystając z Delphi, można ten kod uzupełnić o anonymouse functions
, ale ja (tj.autor tego kodu) akurat nie jestem w posiadaniu takiego.
Jak ktoś chce, może śmiało edytować ten kod.
Kod wrzucam, ponieważ może komuś się przydać.
Tak, niestety dla leniwego wywołania trzeba pokombinować.
O ile pamiętam, po podstawieniu funkcji za parametr (korzystając z Twojego kodu), zostanie ona wywołana tak czy siak.
Dało się to co prawda uniknąć wskaźnikami, no ale...
Tyle zachodu żeby zrobić VBasicowego IIF-a...
A wystarczy:
function IIF(const ACondition: boolean;
const ATrueValue, AFalseValue: Variant): Variant;
begin
if ACondition then
Result := ATrueValue
else
Result := AFalseValue;
end;
A potem:
WriteSimpleElement('Enabled', IIF(Self.Enabled, 'True', 'False'));