Перейти к содержимому
  • 0
Zer0Galaxy

Функции и значения, которые они возвращают

Вопрос

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

function foo()
  return 2,3,4
end

Вызов этой функции можно вставить в качестве параметра в другую функцию. Например:

print(foo()) --> 2    3    4

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

К этому списку можно добавить еще элементы, но только в начало.

print(1,foo()) --> 1    2    3    4

Если же мы попытаемся добавить элемент в конец списка ...

print(1,foo(),5) --> 1    2    5

... то обнаружим, что внутренняя функция передает во внешнюю только один элемент - первый.

Почему так происходит и как сделать так, что бы передавались все элементы?

print(1,foo(),5) --> 1    2    3    4    5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

@@Zer0Galaxy, недавно об том говорили в ирке, так и не нашли решения. Но @Totoro посчитал это логичным, так как мы явно указываем что результат функции foo() занимает только один элемент.

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

Изменено пользователем LeshaInc

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

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

function foo()
  return 2,3,4
end

Вызов этой функции можно вставить в качестве параметра в другую функцию. Например:

print(foo()) --> 2    3    4

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

К этому списку можно добавить еще элементы, но только в начало.

print(1,foo()) --> 1    2    3    4

Если же мы попытаемся добавить элемент в конец списка ...

print(1,foo(),5) --> 1    2    5

... то обнаружим, что внутренняя функция передает во внешнюю только один элемент - первый.

Почему так происходит и как сделать так, что бы передавались все элементы?

print(1,foo(),5) --> 1    2    3    4    5

В Java тоже такая штука, скажу одно, стэк, аргументы попадают в стэк - это касается луа, по видимо - это сделано из за того что можно переполнить его, 1 аргумент - константа, 2 аргумент - это переменное количество, 3 аргумент опять константа, вероятно всего foo() может переполнить стэк, тогда 5 не попадёт, а если в конце переменное количество, можно просто положить туда сколько осталось в стэке места. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

Но Totoro посчитал это логичным, так как мы явно указываем что результат функции foo() занимает только один элемент.

абсолютно верно. 

 

 

П.С.

Синтаксис для переменного числа параметров:

function f(x, y, ...)
end

и только так, и не получится запихнуть foo() между ", foo(), "  Будет принято в качестве значения аргумента только первое, возвращаемое ф-цией foo(), значение.

 

 

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

function foo()
  return {e1=2, e2=3, e3=4}
end

print(1, foo(), 5)  --> 1  table: 0x000000  5
print(1, foo().e3, 5) --> 1  4  5

тогда мы точно и гарантировано ничего нигде не потеряем случайно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

function foo() return {e1=2, e2=3, e3=4} end

Почему foo() функция, если можно переменную foo использовать с таким же успехом как таблицу? (экономя 2 символа причём)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Почему foo() функция, если можно переменную foo использовать с таким же успехом как таблицу? (экономя 2 символа причём)

 

Ну, в программах надо экономить не символы. :D

 

А функцию юзать или таблицу - зависит от контекста.

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

А если не понадобится - то вообще места не займёт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

 

То есть эта таблица не будет занимать память, ровно до того момента, когда она понадобится где-то в коде.

Но почему? Разве функция не должна в себе хранить всю информацию что, в ней описана? (а этой информации больше, так кроме самой таблицы, там будут записаны ещё и команды для её создания) 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Но почему? Разве функция не должна в себе хранить всю информацию что, в ней описана? (а этой информации больше, так кроме самой таблицы, там будут записаны ещё и команды для её создания) 

 

Гм. Справедливо. Надо протестить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Почему foo() функция, если можно переменную foo использовать с таким же успехом как таблицу?

Ну луа - это одна сплошная таблица, и сам того не замечая, ты ее и используешь всегда =)

Ф-ция foo - функция, потому что в топике речь шла о функциях и передачи их возврата в качестве параметров в другие функции.

 

П.С. А так функция foo стала уже функцией на твой взгляд? Или это все еще таблица и можно экономить символы? Как считаешь?)

function foo(a)
  print('я функция :(')
  return {
  e1=2, 
  e2=3, 
  e3=a + 25,
  f=function(c, text)
    local b = a^2+c
    print(text)
    return b, 'возврат в таблицу {...}'
  end
  }
end

print(1, foo(5).e3, 5)
print(1, foo(10).f(1,'Бобик, ко мне!'))

------------------------------------------
я функция :(
1	30	5

я функция :(
Бобик, ко мне!
1	101.0	возврат в таблицу {...}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

function foo()
return {e1=2, e2=3, e3=4}
end
--отличается от
foo={e1=2, e2=3, e3=4}
--тем, что при каждом вызове функции таблица будет создана новая, а в переменной она создается при инициализации

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Ну луа - это одна сплошная таблица, и сам того не замечая, ты ее и используешь всегда =)

Ф-ция foo - функция, потому что в топике речь шла о функциях и передачи их возврата в качестве параметров в другие функции.

 

П.С. А так функция foo стала уже функцией на твой взгляд? Или это все еще таблица и можно экономить символы? Как считаешь?)

function foo(a)
  print('я функция :(')
  return {
  e1=2, 
  e2=3, 
  e3=a + 25,
  f=function(c, text)
    local b = a^2+c
    print(text)
    return b, 'возврат в таблицу {...}'
  end
  }
end

print(1, foo(5).e3, 5)
print(1, foo(10).f(1,'Бобик, ко мне!'))

------------------------------------------
я функция 
1	30	5

я функция 
Бобик, ко мне!
1	101.0	возврат в таблицу {...}

Да мне просто хочется узнать что меньше весит и почему. Чтобы оптимизировать код. И тут я думаю что функции весят больше. Кто нибудь ответит на этот вопрос?

 

P.S. потому что по коду и ответу я не врубился где ответ на вопрос, что больше занимает памяти.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@@qwertyMAN, да в общем надо понимать назначение функций и назначение других типов. Функция может производить важные вычисления исходя из ее аргументов и возвращать результат в таблице:

local function foo(a, b)
  return {
    a = a ^ b * 3,
    b = b ^ a * 6
  }
end

Если же функция выдает статический результат:

local function foo()
  return {answer = 42}
end

... то смысла так делать нет. Каждый раз при вызове foo будет создана новая таблица, с новым идентификатором, с новыми ключами, с новыми значениями. Это все аллоцируется в памяти заново. Это может быть полезно, но не в этом случае.

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

local foo = {answer = 42}

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...