Можно ли заменить массив XXX на TArray <XXX>
У меня довольно много переменных, объявленных как
var
Something: array of XXX;
begin
SetLength(Something, 10);
try
...
finally
SetLength(Something, 0);
end;
end;
В какой степени безопасно заменить их:
var
Something: TArray<XXX>;
begin
SetLength(Something, 10);
try
...
finally
SetLength(Something, 0);
end;
end;
Ответы
Ответ 1
Как уже было сказано, TArray<XXX>
точно соответствует любому другому пользовательскому типу, определенному как array of XXX
. Фактически, TArray<XXX>
- это настраиваемый тип, определенный как array of XXX
.
Тем не менее, пользовательский тип, определенный как array of XXX
, не эквивалентен array of XXX
в контексте параметра процедуры или функции. procedure Foo(x: array of Integer)
x
- это параметр открытого массива, который может принимать любой тип целочисленного массива. Напротив, procedure Foo(x: TArray<Integer>)
принимает только фактический тип TArray<Integer>
. Вы можете увидеть разницу при попытке передать массив фиксированного размера, но также при попытке передать TDynIntegerArray
(другой тип, также определенный как array of Integer
).
Итак, для переменных обязательно, если у вас есть array of XXX
, измените его на TArray<XXX>
все, что вы хотите. Просто убедитесь, что вы не выполняете глобальный поиск и не заменяете.
Ответ 2
Это абсолютно безопасно. Компилятор будет выдавать идентичный результат.
Я лично, при прочих равных условиях, рекомендую это сделать. Использование общего массива TArray<T>
дает вам гораздо большую гибкость и лучшую совместимость с типом.
Конечно, эти преимущества можно увидеть только с более реалистичным кодом, который выполняет определенную работу. Обычно вы используете преимущества при использовании универсальных контейнеров. Но вы также можете увидеть преимущества при создании кода с использованием нескольких разных библиотек.
Использование общих массивов позволяет легко совместимость типов. Перед генераторными массивами вы определяете тип массива следующим образом:
TIntArray = array of Integer;
Если две библиотеки делают это, то у вас есть несовместимые типы. Если библиотеки согласятся использовать общие массивы, тогда будет совместимость.
Чтобы увидеть это более четко, рассмотрим этот фрагмент:
type
TIntArray1 = array of Integer;
TIntArray2 = array of Integer;
....
var
arr1: TIntArray1;
arr2: TIntArray2;
....
arr1 := arr2;
Это присвоение недопустимо и не выполняется с ошибкой компилятора типа неправильного соответствия. Этого вполне можно ожидать на языке Паскаля. Это, в конце концов, строго типизировано, и это разные типы. Даже если они выполняются одинаково.
С другой стороны:
var
arr1: TArray<Integer>;
arr2: TArray<Integer>;
....
arr1 := arr2;
действителен и компилируется. документация для совместимости с общим типом говорит:
Два экземпляра генерируемых экземпляра считаются совместимыми, если базовые типы идентичны (или являются псевдонимами для общего типа), а аргументы типа идентичны.