Skip to content

Продвинутое использование

Конструкторы

Для классов 1Скрипт можно создавать параметризованные конструкторы. Тогда класс, создаваемый через Новый будет требовать передачи параметров конструктора. Конструктор это метод со специальным именем ПриСозданииОбъекта.

Объявление конструктора

bsl
Перем мПереданноеИзвнеЗначение1;
Перем мПереданноеИзвнеЗначение2;

Процедура ПриСозданииОбъекта(Значение1, Значение2)
    мПереданноеИзвнеЗначение1 = Значение1;
    мПереданноеИзвнеЗначение2 = Значение2;
КонецПроцедуры

В примере выше объявляется конструктор с двумя параметрами. В этом случае класс (пусть он называется МойКласс для примера) может быть создан следующим образом:

bsl
// Параметры конструктора попадут в метод ПриСозданииОбъекта
ОбъектМоегоКласса = Новый МойКласс(ТекущаяДата(), "Слава 1С");

Строковое представление

Можно переопределять стандартное строковое представление для своих классов. Для этого используется метод со специальным названием ОбработкаПолученияПредставления.

bsl
Процедура ОбработкаПолученияПредставления(Значение, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Значение = "Этот класс будет иметь измененное представление в виде строки"
КонецПроцедуры

Аннотации

1Скрипт поддерживает аннотирование методов, переменных и параметров с помощью собственных Аннотаций. Аннотация обозначается символом & и является дополнительным признаком к аннотируемой сущности. В дальнейшем аннотации можно получать с помощью класса Рефлектор.

Аннотации широко используются в библиотеках тестирования и фреймворке ОСень.

Синтаксис аннотаций

Аннотация имеет обязательное Имя, и в скобках перечисление параметров аннотации

bsl
&АннотацияДляМетода // без параметров
&ЕщеОднаАннотация(1, 2, "Привет") // со значениями
Процедура Пример(
    // аннотация на параметре метода, с указанием именованного параметра аннотации
    &АннотацияПараметра(Признак = Истина) 
    ПараметрМетода
)
    // Тело метода
КонецПроцедуры

Параметры аннотации могут принимать следующий вид:

  • Идентификатор
  • Обычное значение
  • Идентификатор и значение

Например:

bsl
&РежимФар(ДальнийСвет) // идентификатор
&РежимФар("Дальний") // значение
&РежимФар(ДальнийСвет, Мощность = 80) // Идентификатор и значение для параметра Мощность

Аннотации совершенно произвольные, их значение и смысл определяется внешним кодом, который получит эти аннотации через рефлектор. Например, фреймворк тестирования собирает все методы, помеченные аннотацией &Тест и понимает, что эти методы надо запустить, как точки входа тестов.

Аннотации модуля

Аннотирован может быть также и весь модуль целиком. Тогда, синтаксис аннотации меняется и аннотация модуля указывается через символ # в самом начале текста модуля.

Итераторы и обходимые коллекции

В 1Скрипт можно определить собственный класс-коллекцию, который будет обходиться через оператор Для Каждого Из Цикл

Для того, чтобы определить такую коллекцию нам потребуется два класса:

  • Собственно, класс коллекции
  • Класс итератора, который будет обходить эту коллекцию

Обходимое. Класс коллекции

Чтобы система поняла, что класс несет специальную функцию, в самом начале модуля должна быть размещена аннотация модуля Обходимое. При этом поддерживается два варианта указания этой аннотации. Ее можно разместить на самом модуле (в начале, через решетку) или на конструкторе класса (процедуре ПриСозданииОбъекта)

bsl
// Первый вариант, аннотация на модуле в целом
#Обходимое 

Функция ЭтоКакаяТоФункцияДальшеИдетКодМодуля()
КонецФункции

или же, второй способ - аннотация размещена на методе конструктора

bsl
&Обходимое
Процедура ПриСозданииОбъекта(ПараметрКонструктора)
КонецПроцедуры

Класс коллекции обязательно должен иметь функцию ПолучитьИтератор() которая вернет итератор по коллекции. Кроме того, рекомендуется создавать в классе метод Количество, который вернет количество элементов в коллекции. Если такого метода не будет, то вызов метода Количество() на коллекции будет выдавать ошибку.

Итератор. Класс итератора

Итератор - это объект который осуществляет проход по коллекции в цикле. Итератор обязан иметь следующие методы:

  • Следующий() - передвигает итератор и возвращает Истина, если это удалось. Возвращает Ложь, если конец коллекции достигнут и больше двигаться некуда.
  • Текущий() - возвращает текущее значение элемента коллекции

Также, итератор может иметь необязательный метод ПриОсвобожденииОбъекта. Он вызывается системой при окончании цикла, когда итератор больше не нужен. В этом методе может быть произведена необходимая очистка ресурсов, если это необходимо.

Итератор размечается аннотацией Итератор, которая так же может быть размещена либо на модуле, либо на методе конструктора. В начальном состоянии итератор должен указывать "в никуда" на позицию до первого элемента. В начальном состоянии значение для метода ТекущийЭлемент не определено и метод не должен вызываться.

Самый первый вызов метода Следующий() перемещает итератор на самый первый элемент.

bsl
Перем Индекс;
Перем Коллекция;
Перем Размер;

&Итератор
Процедура ПриСозданииОбъекта(пКоллекция)
    Коллекция = пКоллекция;
    Индекс = -1;
    Размер = Коллекция.Количество();
КонецПроцедуры

Функция Следующий()
    Если Индекс < Размер-1 Тогда
        Индекс = Индекс + 1;
        Возврат Истина;
    Иначе
        Возврат Ложь;    
    КонецЕсли;
КонецФункции

Функция ТекущийЭлемент()
    Возврат Коллекция.Получить(Индекс);
КонецФункции

Пример

Сначала опишем класс коллекции

bsl
// файл СлучайнаяПоследовательность.os

Перем ДлинаКоллекции;

&Обходимое
Процедура ПриСозданииОбъекта(Длина)
    ДлинаКоллекции = Длина;
КонецПроцедуры

Функция Количество()
    Возврат ДлинаКоллекции;
КонецФункции

Функция ПолучитьИтератор()
    Возврат Новый ИтераторСлучайныхЧисел(ДлинаКоллекции);
КонецФункции

// Переопределим представление
Процедура ОбработкаПолученияПредставления(Значение, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    Значение = "СлучайнаяПоследовательность(" + ДлинаКоллекции + ")";
КонецПроцедуры

Затем опишем класс итератора

bsl
// Файл ИтераторСлучайныхЧисел.os
Перем Предел;
Перем ГСЧ;

Перем ТекущийЭлемент;
Перем Получено;

&Итератор
Процедура ПриСозданииОбъекта(Длина)
    // Инициализация внутреннего состояния итератора
    Предел = Длина;
    ГСЧ = Новый ГенераторСлучайныхЧисел;
    
    // Сформируем самый первый элемент;
    ТекущийЭлемент = Неопределено;
    Получено = 0;
КонецПроцедуры

Функция Следующий()
    Если Получено < Предел Тогда
        // Не достигли предела
        // формируем очередное значение
        ТекущийЭлемент = ГСЧ.СлучайноеЧисло(0, 1000);

        // Увеличиваем счетчик
        Получено = Получено + 1;

        Возврат Истина;
    Иначе
        Возврат Ложь;
    КонецЕсли;
КонецФункции

Функция ТекущийЭлемент()
    // метод ТекущийЭлемент должен всегда возвращать одно и то же значение
    // между вызовами метода Следующий()
    Возврат ТекущийЭлемент;
КонецФункции

Теперь, воспользуемся нашей специальной коллекцией

bsl
СлучайнаяПоследовательность = Новый СлучайнаяПоследовательность(5);
Для Каждого ОчередноеЧисло Из СлучайнаяПоследовательность Цикл
    Сообщить(ОчередноеЧисло); // выведет случайное число 5 раз
КонецЦикла;