Передача параметров по значению в языке 1С

26.11.20

Разработка - Механизмы платформы 1С

Все мы знаем, что в 1С можно написать такое: Процедура ОбработатьОбъект(Знач Объект) КонецПроцедуры Т.е. тем самым мы передаем в процедуру параметр по значению Далее в статье будут рассмотрены некоторые особенности передачи по значению объектов НЕпримитивных типов.

Итак.

Все мы знаем, что в 1С можно написать такое:

Процедура ОбработатьОбъект(Знач Объект)

КонецПроцедуры

Т.е. тем самым мы передаем в процедуру параметр по значению.

 

Затем можем написать Эксперимент 1

Процедура ОбработатьОбъект(Знач Объект)

Объект = 3;
Сообщить(Объект);
КонецПроцедуры
А = 2;
Сообщить(А);
ОбработатьОбъект(А);
Сообщить(А);

И получим в итоге:

2

3

2

 

Далее можем сделать Эксперимент 2

Процедура ОбработатьОбъект(Знач Объект)

Объект.Очистить();
Сообщить(Объект.Количество());
КонецПроцедуры
А = Новый Массив;
А.Добавить(1);
А.Добавить(2);
А.Добавить(3);
А.Добавить(4);
Сообщить(А.Количество());
ОбработатьОбъект(А);
Сообщить(А.Количество());

И получим в итоге:

4

0

0

Но можем, наконец, провести Эксперимент 3:

Процедура ОбработатьОбъект(Знач Объект)

Объект = Новый Массив;
Сообщить(Объект.Количество());
КонецПроцедуры
А = Новый Массив;
А.Добавить(1);
А.Добавить(2);
А.Добавить(3);
А.Добавить(4);
Сообщить(А.Количество());
ОбработатьОбъект(А);
Сообщить(А.Количество());

И получим в итоге:

4

0

4

 

Выводы

Вывод из первого эксперимента простой – с примитивными типами использование Знач допустимо и работает ожидаемо.

Вывод из второго эксперимента, казалось бы, тоже простой – как минимум с коллекциями значений использование Знач НЕ работает или работает НЕ ожидаемо.

А вот вывод из третьего эксперимента гораздо интереснее – использование Знач с коллекциями значений (и прочими НЕ примитивными типами) работает, все-таки, ожидаемо!!!

 

Если кому-то интересны причины таких результатов – читайте дальше.

 

Теперь разберем механику

 Для понимания механики обратимся сначала к трем более базовым темам программирования:

1)       механика создания переменных (на уровне компилятора/интерпретатора)

2)       работа с указателями на область памяти (я сознательно НЕ пишу выражение «ссылка на область памяти», чтобы не смешивать разные для 1С понятия в слове «ссылка»)

3)       механика передачи параметров при вызове процедур и функций

 

Начнем.

 

Механика создания переменных

В процессе выполнения программы при создании и инициализации переменной система (компилятор или интерпретатор) производит следующее:

- заведение в таблице переменных новой строки для этой новой переменной

- резервирование некоего участка памяти

- занесение в одну из ячеек созданной строки адреса этого участка памяти

- заполнение выделенного участка памяти требуемым значением

 

Далее.

Работа с указателями на область памяти

Для примитивных типов это (механизм создания переменных) работает один в один.

Для НЕ примитивных типов это работает сложнее: в зарезервированный участок памяти помещается указатель на другой участок памяти, в котором уже и хранятся требуемые данные.

 

И наконец - Механика передачи параметров при вызове процедур и функций

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

Если в описании процедуры параметр описан со словом Знач, то перед помещением в стек система (компилятор/интерпретатор) производит

- выделение нового участка памяти

- копирование в выделенный участок содержимого того участка памяти, на который показывает указатель из таблицы переменных

- помещение в стек указателя на выделенный участок памяти.

Тем самым – при возврате из процедуры содержимое старого участка памяти остается НЕТРОНУТЫМ.

 

Ну а далее все просто: во всех трех экспериментах при создании стека параметров произошло одно и то же - произошло копирование участка памяти со значением переменной А.

НО:

В эксперименте 1 скопировалось непосредственно значение 2.

В эксперименте 2 скопировался только указатель на ту область памяти, в которой был размещен массив.

Потому работа с массивом внутри процедуры привела к работе с самим массивом.

В эксперименте 3 произошло абсолютно то же самое, что и в эксперименте 2.

НО потом во вновь выделенный участок памяти был помещен указатель на вновь созданный массив!

Тем самым мы работали с новым массивом, а старый массив остался НЕТРОНУТЫМ.

 

Отсюда следует простой вывод – в 1С передача параметра по значению работает ожидаемо: копируется значение из участка памяти, на который указывает соответствующая ячейка таблицы переменных.

Т.е. для примитивных типов копируются непосредственно данные (т.е. само значение).

А вот для НЕ примитивных типов копируется лишь указатель на непосредственно данные.

 

Почему так

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

А это:

1) затратно в плане времени исполнения и использования памяти (ведь коллекция может быть большой)

2) не все НЕпримитивные типы в 1С могут быть сериализованы и десериализованы.

 

Как с этим жить

Один из обходных вариантов

- перед вызовом процедуры делать ЗначениеВСтрокуВнутр()/сериализацию в XML/помещать в хранилище значения/проч.,

- передать в процедуру полученную строку,

- а в самой процедуре вызвать ЗначениеИзСтрокиВнутр()/десериализацию из XML/извлечение из хранилища/проч..

Но, повторюсь, - не со всеми типами это сработает!

знач передача по значению сериализация

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7443    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5942    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    17663    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11221    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23756    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18828    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14729    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. FesenkoA 58 26.11.20 14:42 Сейчас в теме
Общаясь с программистами, я понимаю что только у меня ЗП не зависит от количества переменных в коде. В чем сложность передать в процедуру переменную Б, присвоив ей значение А? А- это форма? копируйте ее данные в значение, а потом назад. А-это А - это какая то сложная свистоперделка из массива, элементами которой являются структуры, ТЗшки, другие массивы, формы, МВТ, КОМ-соединения, результаты запросов - разбейте своего монстра на несколько переменных/процедур, не превращайте код в Вавилон.
2. lvictor58 137 27.11.20 12:52 Сейчас в теме
Эксперименты на уровне младшей группы детского сада "Если муравью оторвать лапки он ставится глухой"!
triviumfan; nico2; +2 Ответить
3. gzharkoj 520 30.11.20 21:22 Сейчас в теме
Такое поведение не очевидно, но они честно это описали давным давно https://its.1c.ru/db/metod8dev/content/2606/hdoc
VsHome; artbear; vardeg; +3 Ответить
5. artbear 1563 01.12.20 14:14 Сейчас в теме
(3) Вот более актуальная ссылка https://its.1c.ru/db/v8318doc#bookmark:dev:TI000000151

1С пишет, что информация по Вашей ссылка устарела.
6. gzharkoj 520 01.12.20 14:24 Сейчас в теме
(5) так ведь ссылка, а не информация, да и показывает, что все это давным-давно известно и описано.
4. artbear 1563 01.12.20 14:11 Сейчас в теме
На сайте уже давно есть статья Андрея Овсянкина про передачу значений, где все сказано

https://infostart.ru/1c/articles/388527/

и у нее 213 плюсов

еще одна статья зачем?
7. awk 744 01.12.20 15:53 Сейчас в теме
(4) Артур, что бы напомнить... Передачу по ссылке или по значению, я прохожу с 1997 года, раз в пять лет регулярно (и не только про 1С) и все равно статья полезна.
8. Darklight 33 01.12.20 16:30 Сейчас в теме
Да - статья примитивна. Ей нахватает очень важного раздела - как поведут себя эти примеры, если вызов на стороне клиента, а вызываемая процедура находится в серверном контексте (доступном с клиента) - можно рассмотреть управляемое и неуправляемое приложение для полной ясности. Ну и, до кучи - в 1С есть ещё один способ вызова функций - через OLE - тоже хорошо было бы рассмотреть передачу переменных в этом случае.
А для полноты повествования - нужно бы это всё подкрепить тестами производительности.
Вот тут да - есть о чём поведать публике, тем, кто ещё с этим не столкнулся. И дать рекомендации - когда использовать а когда не использовать "Знач".
Кстати, если уж совсем углубляться, то хорошо бы привести и исторический экскурс - почему аргументы функций, в большинстве языков, передаются по умолчанию по значению, а, в 1С, наоборот - по ссылке. Но тут уже да - очень уж нужно углубляться в историю и механику исполнения тех или иных платформ. Зато многое прояснилось бы - как надо поступать в тех или иных ситуациях.

Эх... жаль в 1С вообще нет понятий мутабельных и не мутабельных переменных/аргументов (хотя есть, но на этом редко в дока офишируют внимание, есть понятия мутабельных и немутабельных объектов - прчиём разделены они между собой очень коряво); как жаль, что нет явно разделения на мутабельные немутабельные коллекции (хотя бы, но в идеале нужно было все встроенные объекты разделять на мутабельные и не мутабельные - и большенству мутабельных объектов делать немутабельную пару - а все немутабельные объекты должны быть ещё и клонируемыми); еслибы ещё кортежи были (немутабельные, всегда передаваемые аргументам по ссылке, а присваиваемые переменным по значению) - эх.... мечты мечты...

P.S.
Любопытно, что сам, лет 5 назад был ещё против немутабельных переменных коллекций - но сейчас осознал, что за ними будущее - нужно только удобно их объявлять и переходить от одной к другой
nekit_rdx; Dementor; Алексей Воробьев; +3 Ответить
9. Jimbo 10 11.12.20 15:06 Сейчас в теме
Познавательно! А что будет со структурами ? И вариант - если в структуру и вложены массивы ??? Никто не ковырялся ?

Как-то в одну неведомую функцию (назовем её черный ящик) отправлял структуру - а она её херила. Добавил в вызове Знач Структура, но так и не проверил, после выхода из функции - структура на месте ли моя.
Оставьте свое сообщение