Есть ли языки программирования с функциями с переменными аргументами не в конце?

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]

Почему бы просто не использовать массивы \ коллекции?

javamonkey79 23.12.2008 09:25

вы могли. тогда зачем вообще нужны * args в Python / C++? кажется, что они нравятся людям.

Claudiu 23.12.2008 09:29

Синтаксический сахар ИМХО; Но каждому свое :)

javamonkey79 23.12.2008 09:44
HTML, CSS dan JS
HTML, CSS dan JS
HTML (HyperText Markup Language) - это язык разметки, используемый для создания и оформления веб-страниц. HTML описывает структуру и содержание...
Каковы некоторые из продвинутых концепций языков программирования?
Каковы некоторые из продвинутых концепций языков программирования?
В языках программирования существует множество продвинутых концепций, но некоторые из них являются наиболее важными:
Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
1
3
639
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Параметры ключевого слова 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:

  1. Для каждого аргумента:
    • если аргумент опущен, нажмите 0
    • если указан аргумент, нажмите 1, а затем нажмите фактическое значение
  2. Увеличьте количество аргументов
  3. Вызвать библиотечную функцию

Следующий 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, который их уже поддерживает (по крайней мере, если вы согласны с тем, что вы можете компилировать и использовать код выше) :)

Johannes Schaub - litb 23.12.2008 10:42

Я думаю, что в этом примере b - всего лишь один аргумент. а в функции g функция f вызывается с тремя аргументами: 1, {2,3,4,5} и 2.

user49117 02.01.2009 01:03

Некоторые языки (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.

Jörg W Mittag 23.12.2008 19:21

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, поэтому, когда я хочу добавить строку, я просто добавляю имя таблицы в качестве первой строки, а остальные - все столбцы. имена, а затем их данные без необходимости сидеть и делать это вручную снова и снова. Удачи!

Другие вопросы по теме