You can only initialize a single local variable per statement.
Can one initialize multiple variables of some type in one line?
-
10-07-2023 - |
Question
I have been trying to write as less code as possible. So, I use:
MyBoolean := Memo1.Text <> '';
instead of
if Memo1.Text = '' then
MyBoolean := true
else
MyBoolean := false;
Declare and initialize
var
myGlobal: integer = 99;
to declare and initialize global variable. I would like to do the same for local variables, but seems it is not possible, so, I wonder if there is a way to initialize multiple variables of some type in one line, like in C
int x, y, z;
x=y=z=0;
Thank you.
Solution 2
OTHER TIPS
In C assignment is an expression (returns a value).
In Pascal assignment is a statement (does not return a value).
The difference has some interesting consequences. For example in C both
while (x=0)
and
while (x==0)
are syntactically valid constructions (it is the source of innumerable errors) while in Pascal
while (x:=0)
is syntactically invalid because x:=0
is a statement.
Of course it would be possible to write a function
function AssignInteger(var _AssignTo: integer; _Value: integer): integer;
begin
Result := _Value;
_AssignTo := _Value;
end;
and use it like this:
var
i, j, k: integer;
begin
i := AssignInteger(j, AssignInteger(k, 5));
But that's not quite what you want, saying you want to write as short as possible code.
I'm pointing this out nonetheless just in case.
As dummzeuch says, you could write your own routine. However, I would prefer one with a signature something like: procedure AssignIntegers(AValue, ATargetArray);
. And ideally call the routine with: AssignInteger(99, [X, Y, Z]);
.
Unfortunately the ideal option does not work, but the following procedure is close enough and should suffice. It works by taking pointers to the integers that need to be assigned.
procedure AssignIntegers(AValue: Integer; const ATargets: array of PInteger);
var
I: Integer;
begin
for I := Low(ATargets) to High(ATargets) do
ATargets[I]^ := AValue;
end;
The following DUnit test case demonstrates that it works. You can even keep an array of these integer pointers handy to reassign at any time.
type
TArrayPInteger = array of PInteger;
procedure TDelphiTests.TestAssignIntegers;
var
X,Y,Z: Integer;
LGroup: TArrayPInteger;
begin
AssignIntegers(1, [@X, @Y, @Z]); { Pass open arrray using addresses of integers to initialise }
CheckEquals(1, X);
CheckEquals(1, Y);
CheckEquals(1, Z);
LGroup := TArrayPInteger.Create(@X, @Y); { Handy technique to initialise dynamic arrays }
AssignIntegers(2, LGroup);
CheckEquals(2, X);
CheckEquals(2, Y);
CheckEquals(1, Z); { Not part of group }
end;
WARNING
The only real drawback is that you lose type-checking. The compiler won't prevent you from passing the address of non-integer types. This can lead to corrupting other structures' data or access violations.