Структура

Общее описание

Структура представляет собой тип, имеющий фиксированный набор полей и методов, а также конструктор. Каждое поле имеет тип, указанный при разработке структуры. Структура может содержать данные, а также описания методов. После описания структуры ее можно использовать в программах наряду с другими типами данных.

Синтаксис объявления структуры:

структура имя-структуры
    [модификатор-обязательности модификатор имя-поля: тип-поля[ = значение-инициализации]]
    [модификатор-обязательности модификатор имя-поля: тип-поля[ = значение-инициализации]]
    [модификатор-обязательности модификатор имя-поля: тип-поля[ = значение-инициализации]]
    ...
    [конструктор]
    ...
    [метод]
    [метод]
;
структура
Ключевое слово, с помощью которого объявляется структура.
имя-структуры
имя-структуры указывает имя описываемой структуры (имя типа). С помощью этого имени в дальнейшем будет происходить использование создаваемой структуры, например, создание переменной с типом структуры. Имя должно удовлетворять общим требованиям к именам в языке.
модификатор-обязательности
Ключевое слово обз, которым обозначаются обязательные поля конструктора. Поля, не отмеченные данным модификатором, являются необязательными. Если значение данных полей не задано при инициализации структуры, в качестве значения будет использоваться значение по умолчанию типа или конструктор типа без параметров (если тип не составной). Если у типа отсутствует значение по умолчанию, и значение по умолчанию не задано разработчиком явно, а также не указан признак обязательности, будет ошибка.
модификатор
Каждое поле структуры объявляется аналогично обычной переменной в модуле. Оно начинается с ключевого слова пер или знч, затем следует имя поля, его тип и необязательное значение инициализации. Имена полей должны соответствовать общим требованиям к именам языка.
Важно: Поле структуры не может быть описано таким образом, чтобы у него был тип самой определяемой структуры. Другими словами, не допускается рекурсивное объявление типа поля.
Имена полей должны быть уникальны в рамках одной структуры.
Если описание поля структуры начинается с модификатора пер, то значение такого поля может быть изменено путем присваивания значения. Если описание поля структуры начинается с модификатора знч, то для такого поля значение может быть установлено только во время создания экземпляра структуры с помощью конструктора.
значение-инициализации
Описывает, какое значение будет принимать поле при создании экземпляра. В качестве значения инициализации может выступать любое выражение, которое вычислимо во время компиляции. Если для поля не задано явное значение инициализации по умолчанию, то используется значение по умолчанию типа или конструктор типа без параметров (если тип не составной). Если у типа отсутствует значение по умолчанию и разработчиком не задано значение по умолчанию для поля явно, а также не указан признак обязательности, будет ошибка.
конструктор
По умолчанию для структуры создается автоматический конструктор, который включает в себя все поля структуры в том порядке, в котором они описаны в самой структуре. Для настройки конструктора используется ключевое слово конструктор, которое в структуре может указываться только один раз. Перед этим ключевым словом могут быть размещены аннотации, которые будут использоваться для настройки конструктора (например, @ИменованныеПараметры). Видимость конструктора соответствует видимости структуры и не может быть изменена.
Пример:
структура МояСтруктура
   пер СтроковоеПоле: Строка
   пер ЧисловоеПоле: Число

   @ИменованныеПараметры
   конструктор
;
метод
Метод структуры — это функция, которая принадлежит структуре и позволяет выполнять различные действия над ее экземплярами или над ней самой. Методы могут быть:
  • Простыми — для работы с экземплярами структуры. Имеют доступ к полям структуры.
  • Статическими — для работы со структурой в целом. Не требуют создания экземпляра структуры. Для объявления используется ключевое слово статический.
Примеры методов:
структура Продажа
    обз пер Товар: Строка
    обз пер Дата: Дата
 
    // Простой метод
    метод ВСтроку(): Строка
        возврат Товар + " " + Дата
    ;

    // Статический метод 
    статический метод ИзСтроки(СтрокаПродажи: Строка): Продажа
        знч Части = СтрокаПродажи.Разделить(" ")
        возврат новый Продажа(Части[0], новый Дата(Части[1]))
    ;
;

Работа со структурой

Очевидно, что первым шагом к использованию собственного типа данных является описание этого типа. Рассмотрим простой пример данных, которые могут быть востребованы в языке: сохранить информацию о каком-либо файле. Допустим, нам необходимо хранить о файле следующую информацию:
  • имя файла;
  • тип файла — исполняемый или не исполняемый;
  • полный путь к файлу;
  • размер файла.

Для этого создадим следующую структуру:

структура ОписаниеФайла
    обз пер ИмяФайла: Строка // имя файла
    обз знч Исполняемый: Булево // тип файла
    обз пер ПолныйПуть: Строка // полный путь
    обз пер РазмерФайла: Число // размер файла
;

Если потребуется описать переменную с типом ОписаниеФайла, то сделать это можно обычным образом: обз пер Файл: ОписаниеФайла;. Если надо сразу инициализировать переменную некоторым значением, то это можно сделать следующим образом (на примере командного процессора ОС Windows 10 версии 1903):

структура ОписаниеФайла
    обз пер ИмяФайла: Строка // имя файла
    обз знч Исполняемый: Булево // тип файла
    обз пер ПолныйПуть: Строка // полный путь
    обз пер РазмерФайла: Число // размер файла
;

метод Скрипт()
    пер КомандныйПроцессор: ОписаниеФайла = новый ОписаниеФайла("cmd.exe",
            Истина,
            "C:\\Windows\\System32\\cmd.exe",
            280064)
;
В данном примере видно, каким образом формируются данные инициализации. Данными инициализации являются значения, указанные через запятую. В примере у структуры явно не указано ни одного конструктора, поэтому используется конструктор по умолчанию. Следовательно, значения, указанные в конструкторе, будут присваиваться полям структуры в следующем порядке: значения конструктора слева направо будут присваиваться полям структуры сверху вниз:
  • свойству ИмяФайла будет присвоена строка cmd.exe;
  • свойству Исполняемый будет присвоено значение Ложь;
  • свойству ПолныйПуть будет присвоена строка C:\\Windows\\System32\\cmd.exe;
  • свойству РазмерФайла будет присвоено значение 280064.

Стоит обратить внимание на то, что свойство Исполняемый указано с модификатором знч. А это означает, что написать выражение КомандныйПроцессор.Исполняемый = Ложь уже не получится.

Очевидно, что в реальной жизни параметры файла следует заполнять, предварительно получив эти значения у файловой системы, но в примере можно пойти на некоторое упрощение и заранее получить нужные значения.

Если теперь нам необходимо получить значение какого-то поля структуры, то для этого потребуется указать имя переменной и имя поля, разделив их символом «точка» — вот так: КомандныйПроцессор.ИмяФайла вернет значение, которое находится в поле ИмяФайла переменной КомандныйПроцессор, описанной с типом структуры ОписаниеФайла. Указанное выражение может использоваться как в качестве источника — для получения значения поля, так и в качестве назначения выражения — для установки значения поля.

Для безопасного динамического обращения к полю структуры рекомендуется использовать механизм отражения с обработкой исключения:
метод ПолучитьЗначениеСвойства(Структура: ОписаниеФайла, Свойство: Строка): Объект?
    пер ОписаниеСвойства: ОтражениеСвойства?
    попытка
        ОписаниеСвойства = Структура.ПолучитьТип().ПолучитьСвойство(Свойство)
    поймать Исключение: ИсключениеОтражения
        возврат Неопределено
    ;
    возврат ОписаниеСвойства.Получить(Структура)
;
Можно также привести переменную к типу неизвестно и вызвать оператор []:
метод ПолучитьЗначениеСвойства(Структура: ОписаниеФайла, Свойство: Строка): Объект?
    возврат (Структура как неизвестно)[Свойство]
;

Сравнение структур

Допустимо сравнение двух значений типа структура на равенство (или неравенство). Две структуры будут считаться равными, если эти структуры одного типа и значения полей попарно совпадают.