Продвинутое использование
Конструкторы
Для классов 1Скрипт можно создавать параметризованные конструкторы. Тогда класс, создаваемый через Новый
будет требовать передачи параметров конструктора. Конструктор это метод со специальным именем ПриСозданииОбъекта
.
Объявление конструктора
Перем мПереданноеИзвнеЗначение1;
Перем мПереданноеИзвнеЗначение2;
Процедура ПриСозданииОбъекта(Значение1, Значение2)
мПереданноеИзвнеЗначение1 = Значение1;
мПереданноеИзвнеЗначение2 = Значение2;
КонецПроцедуры
В примере выше объявляется конструктор с двумя параметрами. В этом случае класс (пусть он называется МойКласс
для примера) может быть создан следующим образом:
// Параметры конструктора попадут в метод ПриСозданииОбъекта
ОбъектМоегоКласса = Новый МойКласс(ТекущаяДата(), "Слава 1С");
Строковое представление
Можно переопределять стандартное строковое представление для своих классов. Для этого используется метод со специальным названием ОбработкаПолученияПредставления
.
Процедура ОбработкаПолученияПредставления(Значение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Значение = "Этот класс будет иметь измененное представление в виде строки"
КонецПроцедуры
Аннотации
1Скрипт поддерживает аннотирование методов, переменных и параметров с помощью собственных Аннотаций
. Аннотация обозначается символом &
и является дополнительным признаком к аннотируемой сущности. В дальнейшем аннотации можно получать с помощью класса Рефлектор.
Аннотации широко используются в библиотеках тестирования и фреймворке ОСень.
Синтаксис аннотаций
Аннотация имеет обязательное Имя, и в скобках перечисление параметров аннотации
&АннотацияДляМетода // без параметров
&ЕщеОднаАннотация(1, 2, "Привет") // со значениями
Процедура Пример(
// аннотация на параметре метода, с указанием именованного параметра аннотации
&АннотацияПараметра(Признак = Истина)
ПараметрМетода
)
// Тело метода
КонецПроцедуры
Параметры аннотации могут принимать следующий вид:
- Идентификатор
- Обычное значение
- Идентификатор и значение
Например:
&РежимФар(ДальнийСвет) // идентификатор
&РежимФар("Дальний") // значение
&РежимФар(ДальнийСвет, Мощность = 80) // Идентификатор и значение для параметра Мощность
Аннотации совершенно произвольные, их значение и смысл определяется внешним кодом, который получит эти аннотации через рефлектор. Например, фреймворк тестирования собирает все методы, помеченные аннотацией &Тест
и понимает, что эти методы надо запустить, как точки входа тестов.
Аннотации модуля
Аннотирован может быть также и весь модуль целиком. Тогда, синтаксис аннотации меняется и аннотация модуля указывается через символ #
в самом начале текста модуля.
Итераторы и обходимые коллекции
В 1Скрипт можно определить собственный класс-коллекцию, который будет обходиться через оператор Для Каждого Из Цикл
Для того, чтобы определить такую коллекцию нам потребуется два класса:
- Собственно, класс коллекции
- Класс итератора, который будет обходить эту коллекцию
Обходимое. Класс коллекции
Чтобы система поняла, что класс несет специальную функцию, в самом начале модуля должна быть размещена аннотация модуля Обходимое
. При этом поддерживается два варианта указания этой аннотации. Ее можно разместить на самом модуле (в начале, через решетку) или на конструкторе класса (процедуре ПриСозданииОбъекта
)
// Первый вариант, аннотация на модуле в целом
#Обходимое
Функция ЭтоКакаяТоФункцияДальшеИдетКодМодуля()
КонецФункции
или же, второй способ - аннотация размещена на методе конструктора
&Обходимое
Процедура ПриСозданииОбъекта(ПараметрКонструктора)
КонецПроцедуры
Класс коллекции обязательно должен иметь функцию ПолучитьИтератор() которая вернет итератор по коллекции. Кроме того, рекомендуется создавать в классе метод Количество
, который вернет количество элементов в коллекции. Если такого метода не будет, то вызов метода Количество() на коллекции будет выдавать ошибку.
Итератор. Класс итератора
Итератор - это объект который осуществляет проход по коллекции в цикле. Итератор обязан иметь следующие методы:
- Следующий() - передвигает итератор и возвращает Истина, если это удалось. Возвращает Ложь, если конец коллекции достигнут и больше двигаться некуда.
- Текущий() - возвращает текущее значение элемента коллекции
Также, итератор может иметь необязательный метод ПриОсвобожденииОбъекта
. Он вызывается системой при окончании цикла, когда итератор больше не нужен. В этом методе может быть произведена необходимая очистка ресурсов, если это необходимо.
Итератор размечается аннотацией Итератор
, которая так же может быть размещена либо на модуле, либо на методе конструктора. В начальном состоянии итератор должен указывать "в никуда" на позицию до первого элемента
. В начальном состоянии значение для метода ТекущийЭлемент не определено и метод не должен вызываться.
Самый первый вызов метода Следующий()
перемещает итератор на самый первый элемент.
Перем Индекс;
Перем Коллекция;
Перем Размер;
&Итератор
Процедура ПриСозданииОбъекта(пКоллекция)
Коллекция = пКоллекция;
Индекс = -1;
Размер = Коллекция.Количество();
КонецПроцедуры
Функция Следующий()
Если Индекс < Размер-1 Тогда
Индекс = Индекс + 1;
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ТекущийЭлемент()
Возврат Коллекция.Получить(Индекс);
КонецФункции
Пример
Сначала опишем класс коллекции
// файл СлучайнаяПоследовательность.os
Перем ДлинаКоллекции;
&Обходимое
Процедура ПриСозданииОбъекта(Длина)
ДлинаКоллекции = Длина;
КонецПроцедуры
Функция Количество()
Возврат ДлинаКоллекции;
КонецФункции
Функция ПолучитьИтератор()
Возврат Новый ИтераторСлучайныхЧисел(ДлинаКоллекции);
КонецФункции
// Переопределим представление
Процедура ОбработкаПолученияПредставления(Значение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Значение = "СлучайнаяПоследовательность(" + ДлинаКоллекции + ")";
КонецПроцедуры
Затем опишем класс итератора
// Файл ИтераторСлучайныхЧисел.os
Перем Предел;
Перем ГСЧ;
Перем ТекущийЭлемент;
Перем Получено;
&Итератор
Процедура ПриСозданииОбъекта(Длина)
// Инициализация внутреннего состояния итератора
Предел = Длина;
ГСЧ = Новый ГенераторСлучайныхЧисел;
// Сформируем самый первый элемент;
ТекущийЭлемент = Неопределено;
Получено = 0;
КонецПроцедуры
Функция Следующий()
Если Получено < Предел Тогда
// Не достигли предела
// формируем очередное значение
ТекущийЭлемент = ГСЧ.СлучайноеЧисло(0, 1000);
// Увеличиваем счетчик
Получено = Получено + 1;
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции
Функция ТекущийЭлемент()
// метод ТекущийЭлемент должен всегда возвращать одно и то же значение
// между вызовами метода Следующий()
Возврат ТекущийЭлемент;
КонецФункции
Теперь, воспользуемся нашей специальной коллекцией
СлучайнаяПоследовательность = Новый СлучайнаяПоследовательность(5);
Для Каждого ОчередноеЧисло Из СлучайнаяПоследовательность Цикл
Сообщить(ОчередноеЧисло); // выведет случайное число 5 раз
КонецЦикла;