Вход | Регистрация

  1  2   

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

Как функции вернуть несколько значений
Я
   vi0
 
03.10.16 - 05:32
1. Возврат структуры50% (11)
3. Свой вариант45% (10)
2. Возврат одного значения и изменение параметров5% (1)
Всего мнений: 22

Поделитесь, какими способами вы пользуетесь при необходимости возврата функцией нескольких значений. И почему.
 
 
   AneJIbcuH
 
1 - 03.10.16 - 05:39
Структура, очень удобно и эффективно использовать.

1. Возврат структуры
   KSergey1C
 
2 - 03.10.16 - 06:07
список, структура, прочитать что в описании процедуры означает слово "Знач".

3. Свой вариант
   Провинциальный 1сник
 
3 - 03.10.16 - 06:12
Структура. А в 7.7 - список значений с обращением по представлению методом "Получить()"

1. Возврат структуры
   VladZ
 
4 - 03.10.16 - 06:13
(0) Структурой удобнее.
   VladZ
 
5 - 03.10.16 - 06:13
забыл проголосовать.

1. Возврат структуры
   Sammo
 
6 - 03.10.16 - 06:16
Зависит от.
Если надо возвращать корректность работы (что функция отработала корректно), то на мой взгляд удобнее возврат Истина/ложь, а параметры в структуре параметров.
Если корректность не имеет смысла - то можно параметрами, можно структурой.
Опять же вопрос - как потом будут использоваться значения. Может как раз структурой для дальнейшего использования удобнее
   vi0
 
7 - 03.10.16 - 06:17
(6) а какая разница как будут использоваться значения?
задача - функция должна вернуть больше одного значения, которые будут использоваться
   Провинциальный 1сник
 
8 - 03.10.16 - 06:18
(6) Вообще, считаю, идеологически правильнее не изменять формальные параметры функцией. Функция в математическом смысле однонаправлена. И у неё четко разделены вход и выход.
А если надо менять параметры внутри - надо создавать процедуру.
   KSergey1C
 
9 - 03.10.16 - 06:23
(8) > Вообще, считаю, идеологически правильнее не изменять формальные параметры функцией. Функция в математическом смысле однонаправлена. И у неё четко разделены вход и выход.

Простой пример: код модуля стал очень сложным, хочется раскидать разные части по отдельным функциям.

Вырезаешь куски в отдельные функции, запускаешь проверку синтаксиса смотришь каких переменных не хваттае и тупо кидаешь их в параметры.
   Провинциальный 1сник
 
10 - 03.10.16 - 06:26
(9) Всё так, но вместо функций тут правильнее юзать процедуры. Идеологическая мешанина процедур и функций - тяжкое наследия языка Си)
 
 Рекламное место пустует
   vi0
 
11 - 03.10.16 - 06:26
(9) так ты поддерживаешь то, то в (8) написано или нет?
   Sammo
 
12 - 03.10.16 - 06:26
(7) Ну вот пример - функция должна вернуть несколько значений, которые потом будут использовать как фильтрующие параметры. Можно вернуть список значений, а можно передать менеджер и сделать временную таблицу
   vi0
 
13 - 03.10.16 - 06:27
(12) ну с временной таблицей это отдельная песня
   KSergey1C
 
14 - 03.10.16 - 06:34
(11) В целом да, но я бы не стал это возводить в абсолют.
   Aleksey
 
15 - 03.10.16 - 06:41
А вариант глобальных перемен это какой вариант?
   vi0
 
16 - 03.10.16 - 06:47
(15) плохой)
   Sammo
 
17 - 03.10.16 - 06:54
(15) В рамках модуля объекта еще туда-сюда.
Более глобальные - не стоит, имхо.
   vcv
 
18 - 03.10.16 - 06:59
Возврат какого-нибудь списка значений тоже не ахти вариант. Сложней в разборе результата функции. Нет подсказки по возвращаемому значению. Легко перепутать "имена" возвращаемых значений. Было бы понятие типа "структуры" - вопросов бы не возникало.
   KSergey1C
 
19 - 03.10.16 - 07:04
(18) 1. Это кто с 7.7 не работал в которых структур не было.
2. Обращаться можно по [0],[1]
   DrZombi
 
20 - 03.10.16 - 07:04
Да чего тут думать? :)

1. Возврат структуры
   vcv
 
21 - 03.10.16 - 07:14
(19) И что, через полгодика вы вспомните, что функция возвращает в [0]? А тем более, если кто-то другой читать код будет. Варианты типа [0] крайне не рекомендуются во всех приличных местах/языках. Варианты типа ["НомерСтелажа"] тоже, слишком велика вероятность опечатки.
   KSergey1C
 
22 - 03.10.16 - 07:33
(21) Так написано же КУДА она её возвращает.
   vcv
 
23 - 03.10.16 - 07:36
(22) Где написано? В коде вы видите что-то типа:
Парам = ПолучитьИтогиДокумента(Накладная);
Наценка = Парам[3]*Парам[2]/Парам[1];
Ну и как этот код читать? За такое в приличных местах уволить нафиг могут.
   Jokero
 
24 - 03.10.16 - 07:36
Идеологически правильнее наверное структурой, но параметрами так удобно))

1. Возврат структуры
   Провинциальный 1сник
 
25 - 03.10.16 - 07:38
(21) Список значений с представлениями позволяет обращаться по имени представления. По сути имитация структуры, которой в семерке нет.
   Провинциальный 1сник
 
26 - 03.10.16 - 07:39
(23) 7.7 - Парам.Получить("Количество")*Парам.Получить("Цена").. как-то так.
   vcv
 
27 - 03.10.16 - 07:47
(25) (26) Ага-ага. А когда-нибудь потом, через полгодика, вы узнаете, что в каком-то нечасто выполняющемся куске кода вместо "Количество" вы написали "Клоичество". И хорошо еще если эта ошибка будет быстро замечена, а не приведёт к постоянным косякам за большой период.
По моему, функции, изменяющие свои параметры, это плохо, но возврат списка или структуры - еще хуже.
Если бы в языке был соответствующий тип вроде сишного union - тогда метод возврата структуры был бы хорош.
   vi0
 
28 - 03.10.16 - 08:13
(27) а чем структура плоха? опечатка приведет к исключению
   Irbis
 
29 - 03.10.16 - 08:17
По частоте использования:
1. Структура, например, если нужно получить что-то связанное с объектом (периодические значения), но получать сам объект не имеет смысла.
2. Функция с параметром, определяющим значение чего будет возвращено.
3. Несколько функций.

(28) Исключение в данном случае благо. Может привести к неверной работе алгоритма, без ошибок времени выплонения.
   vi0
 
30 - 03.10.16 - 08:17
(29) про это и говорю, что благо, и проблемы здесь нет с опечатками
   gigi789
 
31 - 03.10.16 - 08:18
winapi стаил. Функция возвращает истина/ложь  (удачно/не удачно). А в параметры кладем значения возврата. В 1с аналог свойство() для структуры.

2. Возврат одного значения и изменение параметров
   jsmith
 
32 - 03.10.16 - 08:20
Разбить ф-ию
   Azverin
 
33 - 03.10.16 - 08:22
часто вижу этот прием в типовых.

1. Возврат структуры
 
 
   jsmith
 
34 - 03.10.16 - 08:22
cdecl плохо
   jsmith
 
35 - 03.10.16 - 08:24
Если структура не класс (семантически), лучше разбить ф-ию.
   gigi789
 
36 - 03.10.16 - 08:25
(33)ни о чём не говорит типовые сейчас достаточно странные люди пишут.
   vi0
 
37 - 03.10.16 - 08:27
(32) не получиться разбить в связанных значениях
например возвращается также ТекстОшибки
   vcv
 
38 - 03.10.16 - 08:34
(28) Структура плоха тем что:
1. Нельзя использовать автодополнение, выше вероятность опечатки
2. Что бы при чтении кода понять, какие параметры могут возвращаться, приходится переходить к определению функции и читать комментарии к ней. Если они еще есть.
3. На опечатки нельзя проверить формально, надеемся на то, что упомянутое вами исключение выскочит при тестировании у разработчика, а не повалит у пользователей в том куске, который разработчик недостаточно протестировал.
3.1. А бывают еще любители избыточного использование Попытка Исключение. Получается вообще взрывоопасная смесь.
4. При рефакторинге могут возникнуть большие проблемы по переделке кучи мест в коде. Не решаемые полуинтеллектуальным поиском с заменой и прочими подобными инструментами.
... можно еще продолжать про недостатки, но юзверя звонят...
   craxx
 
39 - 03.10.16 - 08:38
(0) структура либо массив
   zak555
 
40 - 03.10.16 - 08:39
(0) соответствие быстрее структуры
   jsmith
 
41 - 03.10.16 - 08:44
Не знал, что map быстрее struct
   jsmith
 
42 - 03.10.16 - 08:46
Хеш-таблицы, понятно
   zak555
 
43 - 03.10.16 - 08:47
(41) вчера об этом на семинаре говорили
   ovrfox
 
44 - 03.10.16 - 09:33
Смотря что имеется в виду под вопросом
Если нужно вернуть все перестановки какого -либо множества, то лучше сделать так, чтобы следующая перестановка возвращалась на основании предыдущей без изменения каких либо параметров.
Если нужно вернуть линейный размеры объект - тогда лучше структура (а еще лучше - сам объект)
А если нужно вернуть сто случайных значений от 0 до 1, то лучше всего возвращать массив.
Т.е. что лучше зависит от контекста вопроса больше, чем от самого вопроса.

3. Свой вариант
   Лефмихалыч
 
45 - 03.10.16 - 09:43
Если функции надо вернуть несколько РАЗНЫХ значений, не объединенных семантически в какое-то целое, значит у тебя косяк в архитектуре и это две функции, а не одна.

А, если эти значения - это атрибуты какого-то одного объекта, то возвращай структуру да и всё.

3. Свой вариант
   vi0
 
46 - 03.10.16 - 10:00
(38)
> 1. Нельзя использовать автодополнение, выше вероятность опечатки
Автодополнение в 1с много где нет? это вопрос тестирования

> 2. Что бы при чтении кода понять, какие параметры могут возвращаться, приходится переходить к определению функции и читать комментарии к ней. Если они еще есть.
Для этого можно в начале функции инициировать структуру, которая нужно вернуть независимо от успешности функции

> 3. На опечатки нельзя проверить формально, надеемся на то, что упомянутое вами исключение выскочит при тестировании у разработчика, а не повалит у пользователей в том куске, который разработчик недостаточно протестировал.
Это совсем другой вопрос - вопрос тестирования.

>  3.1. А бывают еще любители избыточного использование Попытка Исключение. Получается вообще взрывоопасная смесь.
Без комментариев

> 4. При рефакторинге могут возникнуть большие проблемы по переделке кучи мест в коде. Не решаемые полуинтеллектуальным поиском с заменой и прочими подобными инструментами.
Например какие проблемы?
   vi0
 
47 - 03.10.16 - 10:04
(44) пример такой:
функция возвращает ссылку на объект
если вернуть ссылку не получилось, то также нужно вернуть текст ошибки
   ovrfox
 
48 - 03.10.16 - 10:29
(47) При данном примере оптимальнее всего возвращать сылку отдельным параметром, а ошибку - результатом функции. (если ошибка пустая - значит параметр содержит ссылку)
   МимохожийОднако
 
49 - 03.10.16 - 10:35
От ситуации зависит. п.1 будет следующим по убыванию

3. Свой вариант
 
 Рекламное место пустует
   IlyaSR
 
50 - 03.10.16 - 10:51
1

1. Возврат структуры
   Mort
 
51 - 03.10.16 - 11:45
Функция должна возвращать одно значение. Если даже это структура.

3. Свой вариант
   vi0
 
52 - 03.10.16 - 11:47
(51) аргументируйте пожалуйста
   Mort
 
53 - 03.10.16 - 11:50
(48) А возвращать в параметрах ещё отстойней.

(52) Кратко пересказать книжки М.Фаулера и Р.Мартина ?
   SoulPower
 
54 - 03.10.16 - 11:52
(53) Да.

1. Возврат структуры
   Mort
 
55 - 03.10.16 - 11:55
(47) Если функция не нашла значение потому что его нет - возвращается пустое значение, если возникла ошибка из-за неверных параметров, функция должна генерить исключение. Как это исключение будет обрабатывать вызывающая сторона - уже пофиг. Если вызывающая сторона подходит ответственно к параметрам вызова функции, она не должна париться над текстом в принципе.


(54) Там много опирается на то, что функция должна делать что-то одно. А если функция должна делать что-то одно, откуда взяться чему-то второму что можно вернуть?
   MetaDon
 
56 - 03.10.16 - 11:56
Возврат одного значения и изменение нужных глобальных переменных

3. Свой вариант
   Mort
 
57 - 03.10.16 - 11:56
+(55) *над текстом ошибки
   vi0
 
58 - 03.10.16 - 11:57
(53) не нужно пересказывать, просто аргументируйте своими словами
   Mort
 
59 - 03.10.16 - 12:03
(58) См(55). Если не убедил - просто посмотри как работает типовая Справочник.XXX.НайтиПоКоду() и аналогичные. Ни одна функция в здравом уме не возвращает текст ошибки и т.п.
   novichok79
 
60 - 03.10.16 - 12:05
возвращаю данные в соответствии или структуре.

1. Возврат структуры
   vi0
 
61 - 03.10.16 - 12:12
(59) а если речь идет о взаимодействии между системами?
1с - драйвер оборудования
1с - 1с по веб-сервсису
и т.п.
   Loky9
 
62 - 03.10.16 - 12:14
(52) Чтобы она могла быть rvalue.
   SiAl-chel
 
63 - 03.10.16 - 12:18
Чаще всего использую возврат структуры, но бывает, что в параметрах возвращал значение, а сама функция возвращала статус успешное завершения функции.

1. Возврат структуры
   Mort
 
64 - 03.10.16 - 12:18
(61) Тогда Попытка + ВызватьИсключение особенно часто используются.
   Torquader
 
65 - 03.10.16 - 14:05
В общем случае, возврат нескольких значений - это массив, соответственно, структура, список и т.п. это более упрощённое понимание массива.
Но, реального возврата нескольких значений из функции всё равно нет - вы возвращаете один объект. И, самое главное, что он создаётся, а потом разрушается, что медленнее, чем если передавать эти несколько параметров в функцию или процедуру по ссылке.

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

Передача же параметров в вызов функции по значению проще для читателя, так как он понимает, что будет возвращено и может не подставлять переменные для тех значений, которые ему не нужны.
   Dmitry1c
 
66 - 03.10.16 - 14:22
}{оливар устроили

3. Свой вариант
   vi0
 
68 - 04.10.16 - 05:27
(65) это все хорошо, но вопрос был:  какими способами вы пользуетесь
   youalex
 
69 - 04.10.16 - 09:24
Структура/Неопределено.
Т.к считать параметры в каждом вызове - напрягает.

1. Возврат структуры
   пипец
 
70 - 04.10.16 - 09:26
при желании и процедурой можно значения возвращать ))) (вернее получать в переменную)
   dmpl
 
71 - 04.10.16 - 09:27
(8) Математически операция А = А + 1 недопустима. Так что не стоит математику переносить на программирование.
   dmpl
 
72 - 04.10.16 - 09:30
(10) В Си процедур не бывает. Только функции с возвратом типа void. Так что и мешанины быть просто не может.
   dmpl
 
73 - 04.10.16 - 09:36
(23) Естественно уволить - нет проверки деления на 0.
   dmpl
 
74 - 04.10.16 - 09:38
(27) Ну создавай структуру с нужными строками в общем модуле отдельной функцией. Тогда очепятка или будет везде, или нигде.
   Torquader
 
75 - 04.10.16 - 09:50
(71) Для математики это будет рекурсия A<-A+1
Просто в математике = это оператор равенства.
   Nuobu
 
76 - 04.10.16 - 10:08
Вставлю своё имхо:
Когда нужно передавать по ссылке и там менять:
1. Когда меняешь движения, дописываешь данные в таблицу, список.
2. Когда у тебя есть большая структура, которая содержит несколько параметров, которые ты будешь использовать и тебе нужно дополнить её.
3. Когда передаёшь "Отказ" и там меняешь его на Ложь.
4. Когда передаёшь форму и добавляешь на неё свои элементы.
5. Когда передаёшь МенеджерВременных таблиц.

Это то, что смог вспомнить.

Во всех остальных случаях нужно возвращать.

3. Свой вариант
   Mort
 
77 - 04.10.16 - 10:21
(76) из всех примеров возврат значения в параметре только там где "отказ" (отстойная конструкция этот отказ). В остальных случаях это изменение состояния существующего объекта, которое в отсутствие ООП приходится выполнять именно так.
   vi0
 
78 - 04.10.16 - 10:23
(76) это ты описываешь, больше процедуры чем функции, по логике
   Провинциальный 1сник
 
79 - 04.10.16 - 13:14
(72) Я знаю. Именно это и создает мешанину в мозгах, когда сишник садится писать на более структурированных языках. У него уже в прошивке отложилось что функция может и должна менять параметры.
   dmpl
 
80 - 04.10.16 - 13:48
(79) В Си как раз все замечательно. Объявил параметр const - значит менять нельзя. Не объявил - значит он может быть изменен. Потому что с учетом требований с скорости работы может потребоваться и результат вернуть, и параметры поменять.
   Torquader
 
81 - 04.10.16 - 21:28
(79) (80) В Си как раз всё просто - если параметр передан по значению (засунут в стек), то в функции будет его копия, а если по указателю, то в функции будет указатель на переменную, которую по указателю можно менять.
А вот в Си++ появились ссылки, когда передаётся как бы значение, но внутри это реализовано как указатель - то есть то, что мы имеем в 1С, если не написали Знач.

И не забываем, что написав Знач, мы получим копию строки - и, если она очень длинная, то можно получить существенное замедление работы.
   vi0
 
82 - 05.10.16 - 04:13
(81) это все круто, конечно, но оффтоп
   Провинциальный 1сник
 
83 - 05.10.16 - 06:29
(81) Суть не в механизме передачи параметров, а именно в том что в Си нет процедур, и для изменения параметров приходится использовать функцию. Именно поэтому пришедшие из Си и создают функции, меняющие параметры. Паскалисты бы так поступать не стали, а написали бы процедуру.
   dmpl
 
84 - 05.10.16 - 08:03
(83) Дык а если надо и параметры изменить, и значение вернуть? Что использовать? А если надо вернуть значение, параметры не менять, но поменять не параметры (например, добавить записи в базу)? Деление на процедуры и функции чисто условное, иначе сам ЯП не давал бы менять параметры в функции.
   notebug
 
85 - 05.10.16 - 09:34
В зависимости от решаемой задачи

3. Свой вариант
   organizm
 
86 - 05.10.16 - 10:01
(85) БИНГО!!!
   organizm
 
87 - 05.10.16 - 10:02
но мне кажется структура отбирает больше памяти, чем просто переменные.
   Провинциальный 1сник
 
88 - 05.10.16 - 10:03
(84) "Деление на процедуры и функции чисто условное, иначе сам ЯП не давал бы менять параметры в функции."
А лучше бы не давал. С точки зрения парадигмы функционального программирования изменение формальных параметров - жуткая ересь)
   dmpl
 
89 - 05.10.16 - 10:19
(88) А ты с многопоточным программированием и реентрантностью работал? Когда один и тот же код и одни и те же переменные могут использоваться одновременно несколькими потоками? И тогда единственный способ не конфликтовать потокам - это передавать указатель на некую структуру со всем контекстом потока в качестве параметра функции? И, соответственно, параметр там в процессе работы меняется.
   Loky9
 
90 - 05.10.16 - 10:43
(89) А с распределёнными вычислениями?
Процедуре передавать аргументы по ссылке можно.
   cybfyv
 
91 - 05.10.16 - 11:04
В Джаве например вообще нельзя передаваемые параметры менять, только возвращать
   dmpl
 
92 - 05.10.16 - 11:05
(90) В том-то и дело, что как только начинается реальная жизнь - вся академичность летит к чертям. Так зачем все усложнять? В процедуре априори должен выполняться код, который не может сгенерировать ошибку (возврат результата через перереданные параметры - это же неакадемично, для возврата результата предназначена функция). Много такого кода в реальных задачах?
   dmpl
 
93 - 05.10.16 - 11:07
(91) Это помогло ей завоевать звание тормозящей и памятежрущей.
   Torquader
 
94 - 05.10.16 - 11:18
(91) Но, в той же java прекрасно как параметры передаются объекты-контейнеры (BOX) в которых можно менять содержимое, не меняя самого контейнера, то есть так они реализовали указатели.

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

(88) Начнём с того, что во многих языках деление на процедуры и функции чисто условно, так как и те и другие могут иметь как выходные так и выходные параметры.
Просто у функции есть основной параметр, который только выходной.
А если смотреть на низком уровне, то все высокоуровневые процедуры и функции - это вызов кода, возвращающего код ошибки исполнения, а все параметры и результаты хранятся в отдельной области памяти.

(93) Там просто сборка мусора работает тогда, когда памяти стало очень мало - в результате - если память есть, то её будут жрать, пока не надоест. Но, есть ключи запуска, где всё это можно ограничить. И ваша java побыстрее 1С будет.
   spock
 
95 - 05.10.16 - 11:27
(89) Я дико извиняюсь, а в каком языке программирования практикуется подход обращения к общим переменным из разных потоков?
   dmpl
 
96 - 05.10.16 - 11:36
(95) Это скорее особенность компилятора. Локальная переменная функции адресуется по контретному смещению (типа [EDI + 0x10h]. Т.о. если 2 процессора выполняют один и тот же код с одним и тем же значением регистра EDI - физически 2 потока будут обращаться к одной и той же ячейке памяти. В принципе, можно для каждого потока использовать свое значение регистра EDI - но тогда для каждого потока придется создавать свою копию всего контекста приложения.
   spock
 
97 - 05.10.16 - 11:42
(96) не буду утомлять наводящими вопросами и приведу сразу ссылку на race condition: https://ru.wikipedia.org/wiki/Состояние_гонки
   dmpl
 
98 - 05.10.16 - 11:48
(97) Как минимум в некоторых реализациях C++ локальная переменная не поможет, поскольку она во всех потоках будет иметь одинаковый адрес. Собственно, так я и познакомился с этой особенностью многопоточной работы.
   spock
 
99 - 05.10.16 - 11:50
(98) Может быть потому что эта локальная переменная (переменная-член класса) была объявлена, как static?
   spock
 
100 - 05.10.16 - 11:57
(0) Все зависит от ситуации.
Если нужно "набрать" несколько значений, то Структурой их очень удобно возвращать.
В другой случае, через параметры принимаем значение, и через них же возвращаем (типа по ссылки).

3. Свой вариант
  1  2   

Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует