Как функции вернуть несколько значений #781948


#0 by vi0
Поделитесь, какими способами вы пользуетесь при необходимости возврата функцией нескольких значений. И почему.
#0 by vi0
Поделитесь, какими способами вы пользуетесь при необходимости возврата функцией нескольких значений. И почему.
#1 by AneJIbcuH
Структура, очень удобно и эффективно использовать.
#2 by KSergey1C
список, структура, прочитать что в описании процедуры означает слово "Знач".
#3 by Провинциальный 1сник
Структура. А в 7.7 - список значений с обращением по представлению методом "Получить"
#4 by VladZ
Структурой удобнее.
#5 by VladZ
забыл проголосовать.
#6 by Sammo
Зависит от. Если надо возвращать корректность работы (что функция отработала корректно), то на мой взгляд удобнее возврат Истина/ложь, а параметры в структуре параметров. Если корректность не имеет смысла - то можно параметрами, можно структурой. Опять же вопрос - как потом будут использоваться значения. Может как раз структурой для дальнейшего использования удобнее
#7 by vi0
а какая разница как будут использоваться значения? задача - функция должна вернуть больше одного значения, которые будут использоваться
#8 by Провинциальный 1сник
Вообще, считаю, идеологически правильнее не изменять формальные параметры функцией. Функция в математическом смысле однонаправлена. И у неё четко разделены вход и выход. А если надо менять параметры внутри - надо создавать процедуру.
#9 by KSergey1C
> Вообще, считаю, идеологически правильнее не изменять формальные параметры функцией. Функция в математическом смысле однонаправлена. И у неё четко разделены вход и выход. Простой пример: код модуля стал очень сложным, хочется раскидать разные части по отдельным функциям. Вырезаешь куски в отдельные функции, запускаешь проверку синтаксиса смотришь каких переменных не хваттае и тупо кидаешь их в параметры.
#10 by Провинциальный 1сник
Всё так, но вместо функций тут правильнее юзать процедуры. Идеологическая мешанина процедур и функций - тяжкое наследия языка Си)
#11 by vi0
так ты поддерживаешь то, то в написано или нет?
#12 by Sammo
Ну вот пример - функция должна вернуть несколько значений, которые потом будут использовать как фильтрующие параметры. Можно вернуть список значений, а можно передать менеджер и сделать временную таблицу
#13 by vi0
ну с временной таблицей это отдельная песня
#14 by KSergey1C
В целом да, но я бы не стал это возводить в абсолют.
#15 by Aleksey
А вариант глобальных перемен это какой вариант?
#16 by vi0
плохой)
#17 by Sammo
В рамках модуля объекта еще туда-сюда. Более глобальные - не стоит, имхо.
#18 by vcv
Возврат какого-нибудь списка значений тоже не ахти вариант. Сложней в разборе результата функции. Нет подсказки по возвращаемому значению. Легко перепутать "имена" возвращаемых значений. Было бы понятие типа "структуры" - вопросов бы не возникало.
#19 by KSergey1C
1. Это кто с 7.7 не работал в которых структур не было. 2. Обращаться можно по [0],[1]
#20 by DrZombi
Да чего тут думать? :)
#21 by vcv
И что, через полгодика вы вспомните, что функция возвращает в [0]? А тем более, если кто-то другой читать код будет. Варианты типа [0] крайне не рекомендуются во всех приличных местах/языках. Варианты типа ["НомерСтелажа"] тоже, слишком велика вероятность опечатки.
#22 by KSergey1C
Так написано же КУДА она её возвращает.
#23 by vcv
Где написано? В коде вы видите что-то типа: Наценка = Парам[3]*Парам[2]/Парам[1]; Ну и как этот код читать? За такое в приличных местах уволить нафиг могут.
#24 by Jokero
Идеологически правильнее наверное структурой, но параметрами так удобно))
#25 by Провинциальный 1сник
Список значений с представлениями позволяет обращаться по имени представления. По сути имитация структуры, которой в семерке нет.
#26 by Провинциальный 1сник
7.7 - Парам.Получить("Количество")*Парам.Получить("Цена").. как-то так.
#27 by vcv
Ага-ага. А когда-нибудь потом, через полгодика, вы узнаете, что в каком-то нечасто выполняющемся куске кода вместо "Количество" вы написали "Клоичество". И хорошо еще если эта ошибка будет быстро замечена, а не приведёт к постоянным косякам за большой период. По моему, функции, изменяющие свои параметры, это плохо, но возврат списка или структуры - еще хуже. Если бы в языке был соответствующий тип вроде сишного union - тогда метод возврата структуры был бы хорош.
#28 by vi0
а чем структура плоха? опечатка приведет к исключению
#29 by Irbis
По частоте использования: 1. Структура, например, если нужно получить что-то связанное с объектом (периодические значения), но получать сам объект не имеет смысла. 2. Функция с параметром, определяющим значение чего будет возвращено. 3. Несколько функций. Исключение в данном случае благо. Может привести к неверной работе алгоритма, без ошибок времени выплонения.
#30 by vi0
про это и говорю, что благо, и проблемы здесь нет с опечатками
#31 by gigi789
winapi стаил. Функция возвращает истина/ложь  (удачно/не удачно). А в параметры кладем значения возврата. В 1с аналог свойство для структуры.
#32 by jsmith
Разбить ф-ию
#33 by Azverin
часто вижу этот прием в типовых.
#34 by jsmith
cdecl плохо
#35 by jsmith
Если структура не класс (семантически), лучше разбить ф-ию.
#36 by gigi789
ни о чём не говорит типовые сейчас достаточно странные люди пишут.
#37 by vi0
не получиться разбить в связанных значениях например возвращается также ТекстОшибки
#38 by vcv
Структура плоха тем что: 1. Нельзя использовать автодополнение, выше вероятность опечатки 2. Что бы при чтении кода понять, какие параметры могут возвращаться, приходится переходить к определению функции и читать комментарии к ней. Если они еще есть. 3. На опечатки нельзя проверить формально, надеемся на то, что упомянутое вами исключение выскочит при тестировании у разработчика, а не повалит у пользователей в том куске, который разработчик недостаточно протестировал. 3.1. А бывают еще любители избыточного использование Попытка Исключение. Получается вообще взрывоопасная смесь. 4. При рефакторинге могут возникнуть большие проблемы по переделке кучи мест в коде. Не решаемые полуинтеллектуальным поиском с заменой и прочими подобными инструментами. ... можно еще продолжать про недостатки, но юзверя звонят...
#39 by craxx
структура либо массив
#40 by zak555
соответствие быстрее структуры
#41 by jsmith
Не знал, что map быстрее struct
#42 by jsmith
Хеш-таблицы, понятно
#43 by zak555
вчера об этом на семинаре говорили
#44 by ovrfox
Смотря что имеется в виду под вопросом Если нужно вернуть все перестановки какого -либо множества, то лучше сделать так, чтобы следующая перестановка возвращалась на основании предыдущей без изменения каких либо параметров. Если нужно вернуть линейный размеры объект - тогда лучше структура (а еще лучше - сам объект) А если нужно вернуть сто случайных значений от 0 до 1, то лучше всего возвращать массив. Т.е. что лучше зависит от контекста вопроса больше, чем от самого вопроса.
#45 by Лефмихалыч
Если функции надо вернуть несколько значений, не объединенных семантически в какое-то целое, значит у тебя косяк в архитектуре и это две функции, а не одна. А, если эти значения - это атрибуты какого-то одного объекта, то возвращай структуру да и всё.
#46 by vi0
> 1. Нельзя использовать автодополнение, выше вероятность опечатки Автодополнение в 1с много где нет? это вопрос тестирования > 2. Что бы при чтении кода понять, какие параметры могут возвращаться, приходится переходить к определению функции и читать комментарии к ней. Если они еще есть. Для этого можно в начале функции инициировать структуру, которая нужно вернуть независимо от успешности функции > 3. На опечатки нельзя проверить формально, надеемся на то, что упомянутое вами исключение выскочит при тестировании у разработчика, а не повалит у пользователей в том куске, который разработчик недостаточно протестировал. Это совсем другой вопрос - вопрос тестирования. >  3.1. А бывают еще любители избыточного использование Попытка Исключение. Получается вообще взрывоопасная смесь. > 4. При рефакторинге могут возникнуть большие проблемы по переделке кучи мест в коде. Не решаемые полуинтеллектуальным поиском с заменой и прочими подобными инструментами. Например какие проблемы?
#47 by vi0
пример такой: функция возвращает ссылку на объект если вернуть ссылку не получилось, то также нужно вернуть текст ошибки
#48 by ovrfox
При данном примере оптимальнее всего возвращать сылку отдельным параметром, а ошибку - результатом функции. (если ошибка пустая - значит параметр содержит ссылку)
#49 by МимохожийОднако
От ситуации зависит. п.1 будет следующим по убыванию
#50 by IlyaSR
1
#51 by Mort
Функция должна возвращать одно значение. Если даже это структура.
#52 by vi0
аргументируйте пожалуйста
#53 by Mort
А возвращать в параметрах ещё отстойней. Кратко пересказать книжки М.Фаулера и Р.Мартина ?
#54 by SoulPower
Да.
#55 by Mort
Если функция не нашла значение потому что его нет - возвращается пустое значение, если возникла ошибка из-за неверных параметров, функция должна генерить исключение. Как это исключение будет обрабатывать вызывающая сторона - уже пофиг. Если вызывающая сторона подходит ответственно к параметрам вызова функции, она не должна париться над текстом в принципе. Там много опирается на то, что функция должна делать что-то одно. А если функция должна делать что-то одно, откуда взяться чему-то второму что можно вернуть?
#56 by MetaDon
Возврат одного значения и изменение нужных глобальных переменных
#57 by Mort
+ *над текстом ошибки
#58 by vi0
не нужно пересказывать, просто аргументируйте своими словами
#59 by Mort
См. Если не убедил - просто посмотри как работает типовая Справочник.XXX.НайтиПоКоду и аналогичные. Ни одна функция в здравом уме не возвращает текст ошибки и т.п.
#60 by novichok79
возвращаю данные в соответствии или структуре.
#61 by vi0
а если речь идет о взаимодействии между системами? 1с - 1с по веб-сервсису и т.п.
#62 by Loky9
Чтобы она могла быть rvalue.
#63 by SiAl-chel
Чаще всего использую возврат структуры, но бывает, что в параметрах возвращал значение, а сама функция возвращала статус успешное завершения функции.
#64 by Mort
Тогда Попытка + ВызватьИсключение особенно часто используются.
#65 by Torquader
В общем случае, возврат нескольких значений - это массив, соответственно, структура, список и т.п. это более упрощённое понимание массива. Но, реального возврата нескольких значений из функции всё равно нет - вы возвращаете один объект. И, самое главное, что он создаётся, а потом разрушается, что медленнее, чем если передавать эти несколько параметров в функцию или процедуру по ссылке. Удобство структуры и списка значений в том, что можно указывать имена значений, что не требует следить за их порядком. Передача же параметров в вызов функции по значению проще для читателя, так как он понимает, что будет возвращено и может не подставлять переменные для тех значений, которые ему не нужны.
#66 by Dmitry1c
}{оливар устроили
#68 by vi0
это все хорошо, но вопрос был:  какими способами вы пользуетесь
#69 by youalex
Структура/Неопределено. Т.к считать параметры в каждом вызове - напрягает.
#70 by пипец
при желании и процедурой можно значения возвращать ))) (вернее получать в переменную)
#71 by dmpl
Математически операция А = А + 1 недопустима. Так что не стоит математику переносить на программирование.
#72 by dmpl
В Си процедур не бывает. Только функции с возвратом типа void. Так что и мешанины быть просто не может.
#73 by dmpl
Естественно уволить - нет проверки деления на 0.
#74 by dmpl
Ну создавай структуру с нужными строками в общем модуле отдельной функцией. Тогда очепятка или будет везде, или нигде.
#75 by Torquader
Для математики это будет рекурсия A<-A+1 Просто в математике = это оператор равенства.
#76 by Nuobu
Вставлю своё имхо: Когда нужно передавать по ссылке и там менять: 1. Когда меняешь движения, дописываешь данные в таблицу, список. 2. Когда у тебя есть большая структура, которая содержит несколько параметров, которые ты будешь использовать и тебе нужно дополнить её. 3. Когда передаёшь "Отказ" и там меняешь его на Ложь. 4. Когда передаёшь форму и добавляешь на неё свои элементы. 5. Когда передаёшь МенеджерВременных таблиц. Это то, что смог вспомнить. Во всех остальных случаях нужно возвращать.
#77 by Mort
из всех примеров возврат значения в параметре только там где "отказ" (отстойная конструкция этот отказ). В остальных случаях это изменение состояния существующего объекта, которое в отсутствие ООП приходится выполнять именно так.
#78 by vi0
это ты описываешь, больше процедуры чем функции, по логике
#79 by Провинциальный 1сник
Я знаю. Именно это и создает мешанину в мозгах, когда сишник садится писать на более структурированных языках. У него уже в прошивке отложилось что функция может и должна менять параметры.
#80 by dmpl
В Си как раз все замечательно. Объявил параметр const - значит менять нельзя. Не объявил - значит он может быть изменен. Потому что с учетом требований с скорости работы может потребоваться и результат вернуть, и параметры поменять.
#81 by Torquader
В Си как раз всё просто - если параметр передан по значению (засунут в стек), то в функции будет его копия, а если по указателю, то в функции будет указатель на переменную, которую по указателю можно менять. А вот в Си++ появились ссылки, когда передаётся как бы значение, но внутри это реализовано как указатель - то есть то, что мы имеем в 1С, если не написали Знач. И не забываем, что написав Знач, мы получим копию строки - и, если она очень длинная, то можно получить существенное замедление работы.
#82 by vi0
это все круто, конечно, но оффтоп
#83 by Провинциальный 1сник
Суть не в механизме передачи параметров, а именно в том что в Си нет процедур, и для изменения параметров приходится использовать функцию. Именно поэтому пришедшие из Си и создают функции, меняющие параметры. Паскалисты бы так поступать не стали, а написали бы процедуру.
#84 by dmpl
Дык а если надо и параметры изменить, и значение вернуть? Что использовать? А если надо вернуть значение, параметры не менять, но поменять не параметры (например, добавить записи в базу)? Деление на процедуры и функции чисто условное, иначе сам ЯП не давал бы менять параметры в функции.
#85 by notebug
В зависимости от решаемой задачи
#86 by organizm
БИНГО!!!
#87 by organizm
но мне кажется структура отбирает больше памяти, чем просто переменные.
#88 by Провинциальный 1сник
"Деление на процедуры и функции чисто условное, иначе сам ЯП не давал бы менять параметры в функции." А лучше бы не давал. С точки зрения парадигмы функционального программирования изменение формальных параметров - жуткая ересь)
#89 by dmpl
А ты с многопоточным программированием и реентрантностью работал? Когда один и тот же код и одни и те же переменные могут использоваться одновременно несколькими потоками? И тогда единственный способ не конфликтовать потокам - это передавать указатель на некую структуру со всем контекстом потока в качестве параметра функции? И, соответственно, параметр там в процессе работы меняется.
#90 by Loky9
А с распределёнными вычислениями? Процедуре передавать аргументы по ссылке можно.
#91 by cybfyv
В Джаве например вообще нельзя передаваемые параметры менять, только возвращать
#92 by dmpl
В том-то и дело, что как только начинается реальная жизнь - вся академичность летит к чертям. Так зачем все усложнять? В процедуре априори должен выполняться код, который не может сгенерировать ошибку (возврат результата через перереданные параметры - это же неакадемично, для возврата результата предназначена функция). Много такого кода в реальных задачах?
#93 by dmpl
Это помогло ей завоевать звание тормозящей и памятежрущей.
#94 by Torquader
Но, в той же java прекрасно как параметры передаются объекты-контейнеры (BOX) в которых можно менять содержимое, не меняя самого контейнера, то есть так они реализовали указатели. Что касается передачи параметра в функцию по указателю, то в том же Си всё остаётся на уровне функции - указатель, как бы мы его не меняли, обратно не возвращается, то если является обычным входным параметром, а вот про то, на что он указывает, никто не говорил - его можно менять, получая доступ к ячейке памяти по указателю. Начнём с того, что во многих языках деление на процедуры и функции чисто условно, так как и те и другие могут иметь как выходные так и выходные параметры. Просто у функции есть основной параметр, который только выходной. А если смотреть на низком уровне, то все высокоуровневые процедуры и функции - это вызов кода, возвращающего код ошибки исполнения, а все параметры и результаты хранятся в отдельной области памяти. Там просто сборка мусора работает тогда, когда памяти стало очень мало - в результате - если память есть, то её будут жрать, пока не надоест. Но, есть ключи запуска, где всё это можно ограничить. И ваша java побыстрее 1С будет.
#95 by spock
Я дико извиняюсь, а в каком языке программирования практикуется подход обращения к общим переменным из разных потоков?
#96 by dmpl
Это скорее особенность компилятора. Локальная переменная функции адресуется по контретному смещению (типа [EDI + 0x10h]. Т.о. если 2 процессора выполняют один и тот же код с одним и тем же значением регистра EDI - физически 2 потока будут обращаться к одной и той же ячейке памяти. В принципе, можно для каждого потока использовать свое значение регистра EDI - но тогда для каждого потока придется создавать свою копию всего контекста приложения.
#97 by spock
не буду утомлять наводящими вопросами и приведу сразу ссылку на race condition:
#98 by dmpl
Как минимум в некоторых реализациях C++ локальная переменная не поможет, поскольку она во всех потоках будет иметь одинаковый адрес. Собственно, так я и познакомился с этой особенностью многопоточной работы.
#99 by spock
Может быть потому что эта локальная переменная (переменная-член класса) была объявлена, как static?
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С