Python, C++, Scheme и другие позволяют определять функции, которые принимают переменное количество аргументов в конце списка аргументов ...
def function(a, b, *args):
#etc...
... это можно назвать следующим образом:
function(1, 2)
function(1, 2, 5, 6, 7, 8)
и т.д ... Существуют ли какие-либо языки, которые позволяют выполнять функции с переменным числом аргументов в другом месте? Что-то вроде этого:
def function(int a, string... args, int theend) {...}
Со всеми этими действительными:
function(1, 2)
function(1, "a", 3)
function(1, "b", "c", 4)
А как насчет необязательных аргументов где-нибудь в списке аргументов?
def function(int a, int? b, int c, int... d) {}
function(1, 2) //a=1, c=2, b=undefined/null/something, d=[]
function(1,2,3) //a=1, b=2, c=3,d=[]
function(1,2,3,4,5) //a=1, b=2, c=3, d=[4,5]
вы могли. тогда зачем вообще нужны * args в Python / C++? кажется, что они нравятся людям.
Синтаксический сахар ИМХО; Но каждому свое :)



Параметры ключевого слова Lisp может быть тем, что вы ищете. Я думаю, что в Ruby есть похожая схема. См. Также Обзор параметров функций Lisp.
Я полагаю, что PHP имеет значение. Вы можете сделать это, чтобы смоделировать то, что вы ищете. Лично я думаю, что это сбивает с толку.
function foo() {
$args = func_get_args(); // returns an array of args
}
В BASIC это было уже много лет.
Например:
LOCATE [row%] [,[column%] [,[cursor%] [,start% [,stop%]]]]
Эта команда устанавливает позицию (строка%, столбец%) курсора, а также указывает размер курсора (начало%, остановка%) и то, действительно ли он виден (курсор%). Здесь все, что указано в квадратных скобках, можно опустить, и если это так, это свойство не изменяется.
Пример использования:
LOCATE , 5
перейти в столбец 5 или
LOCATE 1, , 0
чтобы перейти к первой строке и сделать курсор невидимым.
Другая команда, в которой это видно, - это команда PUT для записи в файлы. Если средний аргумент (позиция поиска файла) опущен, запись происходит сразу после предыдущей записи.
Важно отметить, что пропуск аргументов наблюдается только во встроенных операторах, а не в пользовательских процедурах и функциях.
С точки зрения реализации, это то, что Microsoft Basic Compiler (BC), похоже, делает для вызова LOCATE:
Следующий C++ может сделать это с помощью такого синтаксиса:
void f(int a, std::initializer_list<int> b, int c) {
// b.begin(), b.end(), b.size() allow to access them
}
void g() {
f(1, { 2, 3, 4, 5 }, 2);
}
да, как оказалось, у C++ появилась версия :) похоже, что новая выйдет в 2010 году. Вы можете поиграть со списками инициализаторов с текущим стволом gcc, который их уже поддерживает (по крайней мере, если вы согласны с тем, что вы можете компилировать и использовать код выше) :)
Я думаю, что в этом примере b - всего лишь один аргумент. а в функции g функция f вызывается с тремя аргументами: 1, {2,3,4,5} и 2.
Некоторые языки (perl, python и многие другие) могут использовать именованные аргументы, которые похожи на выполнение необязательных аргументов в любом месте списка параметров ... (Именованные параметры могут появляться в любом порядке, и любой из них можно сделать необязательным .. .) Они не совсем то же самое, но они близки ...
Не уверен насчет varargs, хотя их обычно можно заменить объектом array / hash / list ...
Будущие версии Ruby (1.9 и выше, Ruby 1.9 планируется выпустить в конце января 2009 г.) могут это сделать.
Однако не всегда очевидно, какое значение привязано к какому параметру.
Вот что принимает Ruby 1.9:
0 или более обязательных аргументов, за которыми следуют 0 или более необязательных аргументов, за которыми следуют 0 или более обязательных аргументов, за которыми следуют остальные аргументы, за которыми следуют 0 или более обязательных аргументов.
Пример:
def meth mand1, opt1 = :def1, o2 = :d2, *args, m2, m3
puts %w[mand1 opt1 o2 m2 args m3].inject('') { |s, arg|
s << "#{arg} = #{(eval arg).inspect}, "
}.gsub /, $/, ''
end
meth :arg1, :a2, :a3
# => mand1 = :arg1, opt1 = :def1, o2 = :d2, m2 = :a2, args = [], m3 = :a3
meth :arg1, :a2, :a3, :a4
# => mand1 = :arg1, opt1 = :a2, o2 = :d2, m2 = :a3, args = [], m3 = :a4
meth :arg1, :a2, :a3, :a4, :a5
# => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a4, args = [], m3 = :a5
meth :arg1, :a2, :a3, :a4, :a5, :a6
# => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a5, args = [:a4], m3 = :a6
meth :arg1, :a2, :a3, :a4, :a5, :a6, :a7
# => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a6, args = [:a4, :a5], m3 = :a7
Как видите, обязательные аргументы связываются первыми как слева, так и справа. Затем связываются необязательные аргументы, и если какие-либо аргументы остаются, они объединяются в массив и привязываются к остальному аргументу.
Ой, подсветка синтаксиса Ruby - это дерьмо исключительно, даже для prettify.js.
R (статистический язык) также имеет это, и он может быть в середине списка, но с тонкой семантикой.
http://cran.r-project.org/doc/manuals/R-intro.html#The-three-dots-argument
> f1 <- function(x,...,y) { return(x+y) }
> f1(1,2)
Error in f1(1, 2) : argument "y" is missing, with no default
> f1(1,y=2)
[1] 3
> f1 <- function(x,...,y) { return(x+y) }
> f1(1,2)
Error in f1(1, 2) : argument "y" is missing, with no default
> f1(1,y=2)
[1] 3
>
Это называется Rest Arguments, и это можно сделать, по крайней мере, на C++ и Java. Google "Остальные аргументы", и вы найдете много данных по этому вопросу с некоторыми примерами, такими как функции, которые будут передавать числа и возвращать среднее значение введенных чисел, возможно, минимальное или максимальное из всех переданных чисел. Как видите, таких функций много, я использовал их в коде для ввода данных в MYSQL, поэтому, когда я хочу добавить строку, я просто добавляю имя таблицы в качестве первой строки, а остальные - все столбцы. имена, а затем их данные без необходимости сидеть и делать это вручную снова и снова. Удачи!
Почему бы просто не использовать массивы \ коллекции?