#delphi #data-structures #structure #record
#delphi #структуры данных #структура #запись
Вопрос:
Кто-нибудь знает, как сделать что-то подобное?
type TFileRecord = record
Name: String;
CreationTimeStamp: DWORD;
Subfiles: Array of TFileRecord;
end;
Я использую Delphi 10.4.
Комментарии:
1. Сэмюэль Андраде: Боюсь, трудно сказать, что именно вы спрашиваете. Если вы скопируете этот код в программу или модуль Delphi и нажмете кнопку компиляции, он будет скомпилирован и будет работать так, как ожидалось.
2. Я предполагаю, что сторонники поддержки понимают, о чем спрашивает OP. Не могли бы вы, пожалуйста, объяснить мне?
3. … динамический массив — это ссылочный тип (просто указатель на объект кучи динамического массива). Итак, хотя ваш приведенный выше код, который использует динамический массив, работает хорошо (
Subfiles
это просто 32-разрядный или 64-разрядный указатель.), теоретически невозможно заменить его статическим массивом. Потому что, если вы подумаете об этом, вы поймете, что это сделало бы размерTFileRecord
бесконечным!4. @SamuelAndrade, я откатил вопрос, поскольку он полностью меняет вопрос. Вам лучше задать новый вопрос.
5. Я поддержал вопрос (после того, как увидел, что у него есть отрицательные голоса), поскольку, хотя вопрос был немного плохо сформулирован (он действительно должен был спросить: «Это допустимая конструкция?»), Было довольно очевидно, что «это допустимо?» это был реальный вопрос, и он был интересным.
Ответ №1:
В моем Delphi 10.4.1, безусловно, возможно иметь такое объявление:
unit TestUnit;
interface
type
TFileRecord = record
Name: String;
CreationTimeStamp: Cardinal; //DWORD;
Subfiles: Array of TFileRecord;
end;
Procedure TestTFR;
implementation
Procedure TestTFR;
var
TFR : TFileRecord;
begin
SetLength(TFR.SubFiles,2);
SetLength(TFR.Subfiles[0].Subfiles,2);
end;
end.
Эта функция была введена в Delphi 2009.
До этого компилятор жаловался на то, что TFileRecord еще не полностью определен.
Как обсуждалось в комментариях, размер динамического массива может быть только размером указателя, что архитекторы компилятора поняли в то время. Зная это, завершение объявления типа не имеет значения для однопроходного компилятора.
Комментарии:
1. Отлично компилируется и в Delphi XE7.
2. Интересно, что это работает только в том случае, если у вас есть объект (может быть либо запись, либо класс), который содержит динамический массив объектов одного и того же типа. Но когда вы пытаетесь объявить объекты, которые имеют тот же тип объекта, что и поле, или содержат статический массив одинаковых типизированных объектов, Delphi выдает ошибку, тип которой еще не полностью определен.
3. Я предполагаю, что компилятор достаточно умен, чтобы знать, что в случае динамического массива объекты, содержащиеся в массиве, будут храниться в их собственных блоках памяти, поэтому их размер не важен при создании объекта, который содержит такой динамический массив. Но если такие объекты будут определены как поля или в массиве фиксированного размера, они могут храниться в том же блоке памяти, что и объект, который их содержит. в таком случае вам нужно заранее знать размер и структуру этого объекта.
4. PS: Кто-нибудь знает хорошую статью или книгу, в которой более подробно объясняется, как Delphi memory Manager хранит разные объекты. Я думаю, это может быть интересным чтением. И да, я знаю, что FastMM является открытым исходным кодом, но я сомневаюсь, что мои знания Delphi достаточно хороши, чтобы понять его внутренности в отношении этого, просто просмотрев его исходный код.
5. @SilverWarior: если тип записи содержит поле своего собственного типа, вы получаете запись бесконечного размера, теоретическую концепцию, которую невозможно реализовать. А статические массивы — это типы значений, так
array[0..3] of X
что это то же самое,record dummy1, dummy2, dummy3, dummy4: X end
что и для заполнения, за исключением. Следовательно, если тип записи содержит поле типа static array самой записи, вы снова получаете эту бесконечную рекурсию и невозможную конструкцию. Все, что вам нужно знать о внутренних форматах данных, находится по адресу docwiki.embarcadero.com/RADStudio/Rio/en /. …