Есть ли языки программирования с функциями с переменными аргументами не в конце? - PullRequest
1 голос
/ 23 декабря 2008

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]

Ответы [ 8 ]

2 голосов
/ 23 декабря 2008

Следующий 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);
}
2 голосов
/ 23 декабря 2008

Бейсик имел это целую вечность.

Например:

LOCATE [row%] [,[column%] [,[cursor%] [,start% [,stop%]]]]

Эта команда задает положение (row%, column%) курсора, а также указывает размер курсора (start%, stop%) и является ли он фактически видимым (cursor%). Здесь все в квадратных скобках можно опустить, и если это так, это свойство не изменяется.

Пример использования:

LOCATE , 5

изменить на столбец 5 или

LOCATE 1, , 0

чтобы перейти к первой строке и сделать курсор невидимым.

Другая команда, в которой это видно, - это команда PUT для записи в файлы. Если средний аргумент (позиция поиска файла) опущен, запись происходит сразу после предыдущей записи.

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

С точки зрения реализации, это то, что Microsoft Basic Compiler (BC) делает для вызова LOCATE:

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

Будущие версии 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

Как видите, обязательные аргументы связаны в первую очередь как слева, так и справа. Затем необязательные аргументы связываются, и если какие-либо аргументы остаются, они объединяются в массив и связываются с остальным аргументом.

1 голос
/ 23 декабря 2008

Несколько языков (perl, python, многие другие) могут делать именованные аргументы, которые похожи на дополнительные аргументы в любом месте списка параметров ... (Именованные параметры могут появляться в любом порядке, и любой из них может быть выполнен необязательно ...) Они не совсем одинаковы, но они близки ...

Не уверен насчет varargs, хотя обычно их можно заменить на объект массива / хеша / списка ...

0 голосов
/ 17 июня 2009

Он называется Rest Arguments и может быть выполнен по крайней мере на C ++ и Java. Google "Rest Arguments", и вы найдете много данных по теме с некоторыми примерами, такими как функции, которые будут передавать числа и возвращать среднее число введенных чисел, может быть, минимум или максимум всех пропущенных чисел. Как вы можете видеть, существует множество вариантов использования таких функций, я использовал их в коде для ввода данных в MYSQL, поэтому, когда я хочу добавить строку, я просто добавляю имя таблицы в качестве первой строки, а все остальные столбцы имена, а затем их данные без необходимости сидеть и вручную делать это снова и снова. Удачи!

0 голосов
/ 23 мая 2009

R (статистический язык) также имеет его, и он может быть в середине списка, но есть тонкая семантика.

http://cran.r -project.org / DOC / Инструкции / R-intro.html # В-три точки-аргумент

> 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
> 
0 голосов
/ 23 декабря 2008

Полагаю, PHP имеет значение. Вы можете сделать это, чтобы имитировать то, что вы ищете. Лично я думаю, что это может сбить с толку.

function foo() {
    $args = func_get_args(); // returns an array of args
}
0 голосов
/ 23 декабря 2008

Параметры ключевых слов Lisp могут быть тем, что вы ищете. Я думаю, что в Ruby есть похожая договоренность. См. Также Обзор параметров функции Lisp .

...