В Delphi строка - это ссылочный тип, который обычно действует как тип значения.Он размещается в куче (а не в стеке, как большинство типов значений) и обладает автоматическим подсчетом ссылок и семантикой копирования при записи.
Чтобы понять, что это значит, рассмотрим, как нормальные значения типов, например, Integer,ведут себя при передаче в качестве параметра в процедуру:
var
gValue: Integer;
procedure PassByValue(aValue: Integer);
begin
// Here @gValue <> @aValue
aValue := aValue + 2;
// Here @gValue <> @aValue
end;
procedure PassByRefrenceInOut(var aValue: Integer);
begin
// Here @gValue = @aValue
aValue := aValue + 2;
// Here @gValue = @aValue
end;
procedure CallProcedures;
begin
gValue := 0;
PassByValue(gValue);
// gValue is still 0
PassByReferenceInOut(gValue);
// gValue is 2
end;
Параметр var в PassByReferenceInOut эквивалентен соглашению C о передаче указателя на аргумент.
Та же семантика применима к строкепередача параметров, но есть небольшая разница во внутреннем представлении значений:
var
gValue: string;
procedure PassByValue(aValue: string);
begin
// Here PChar(gValue) = PChar(aValue) <<<<
aValue := aValue + '2';
// Here PChar(gValue) <> PChar(aValue)
end;
procedure PassByRefrenceInOut(var aValue: string);
begin
// Here PChar(gValue) = PChar(aValue)
aValue := aValue + '2';
// Here PChar(gValue) = PChar(aValue)
end;
procedure CallProcedures;
begin
gValue := '';
PassByValue(gValue);
// gValue is still ''
PassByReferenceInOut(gValue);
// gValue is '2'
end;
Если вы хотите убедиться, что процедура работает с собственной копией строкового значения, используйте процедуру UniqueString, например:
procedure PassByValue(aValue: string);
begin
// Here PChar(gValue) = PChar(aValue)
UniqueString(aValue);
// Here PChar(gValue) <> PChar(aValue)
aValue := aValue + '2';
// Here PChar(gValue) <> PChar(aValue)
end;