Почему необязательные параметры должны появляться в конце декларации
Во всех языках программирования, поддерживающих необязательные параметры, которые я видел, есть имитация того, что необязательные параметры должны появляться в конце объявления. После необязательного элемента могут быть включены никакие требуемые параметры.
В чем причина этого? Я предполагаю, что это может быть требование компилятора/интерпретатора.
Ответы
Ответ 1
Хорошо, если бы они были на фронте, как бы вы обнаружили, когда они перестали поставляться? Единственный способ был бы, если бы тип переменной отличался после дополнительных параметров. Немного странного требования, поэтому имеет смысл, что вы просто заставляете их быть последними (за исключением проблем сложных правил для определения "окончательного" необязательного параметра).
Кроме того, это самый естественный способ сделать это при вызове функции.
Ответ 2
Это просто произвольное правило, созданное разработчиками этих конкретных языков. Нет абсолютно никакой технической причины, почему это ограничение должно быть там.
Он отлично работает в Ruby:
def foo(m1, m2, o1='o1', o2='o2', *rest, m3, m4)
return m1, m2, o1, o2, rest, m3, m4
end
foo(1, 2, 3, 4)
# => [1, 2, 'o1', 'o2', [], 3, 4]
foo(1, 2, 3, 4, 5)
# => [1, 2, 3, 'o2', [], 4, 5]
foo(1, 2, 3, 4, 5, 6)
# => [1, 2, 3, 4, [], 5, 6]
foo(1, 2, 3, 4, 5, 6, 7)
# => [1, 2, 3, 4, [5], 6, 7]
foo(1, 2, 3, 4, 5, 6, 7, 8)
# => [1, 2, 3, 4, [5, 6], 7, 8]
Все обязательные аргументы должны быть предоставлены:
foo(1, 2, 3)
# => ArgumentError: wrong number of arguments (3 for 4)
Без параметра rest, подача более чем number_of_mandatory + number_of_optional аргументов является ошибкой:
def bar(m1, m2, o1='o1', o2='o2', m3, m4)
return m1, m2, o1, o2, m3, m4
end
bar(1, 2, 3, 4, 5, 6, 7)
# => ArgumentError: wrong number of arguments (7 for 6)
Обязательные параметры в начале списка параметров привязаны слева направо от начала списка аргументов. Обязательные параметры в конце списка параметров привязаны справа налево от конца списка аргументов. Необязательные параметры привязаны слева направо от начала оставшегося списка аргументов. Все оставшиеся аргументы связаны с аргументами rest.
Ответ 3
Рассмотрим объявление типа:
int foo(float a, int b=0, int c=0, float d);
(обратите внимание, как я определил defult параметры в середине списка), который впоследствии называется как
foo(0.0,1,2.0)
Что такое звонок? В частности, пропущено b
или c
?
Разработчики компилятора могут обойти это, используя именованные параметры
foo(a=0,c=0,d=2.0)
функция, доступная в python, например.
Ответ 4
Просто угадать в дикой природе: возможно, это связано с вызовами условных обозначений (например, параметры вставляются в стек слева направо, необязательные параметры просто не учитываются, если они не указаны).
Ответ 5
Дополнительные параметры в конце позволяют вам прекратить указывать параметры в какой-то момент, например.
void Test(int a, optional int b = 0, optional int c = 0) { ... }
Test(3);
Если вы сделаете c
требуемый параметр, вам придется использовать синтаксисы, подобные этому:
Test(3, , 2);
Test(a := 3, c := 2);
Преимущество необязательного параметра заключается в том, что его можно рассматривать так, как если бы его не было. Если дополнительные параметры находятся в середине списка параметров, это невозможно без "подсчета запятых" или с использованием слишком подробного синтаксиса.
Ответ 6
Java и С# не имеют именованных параметров, поэтому вы не можете делать:
myfunction(param1='Meh', optionalParam=2)
Вам нужно сделать:
myfunction('Meh', 2)
В противном случае
myFunction(2, 'Meh')
Является неоднозначным. Как компилятор должен знать, что вы имели в виду 2, чтобы быть в необязательном наборе параметров?