Почему необязательные параметры должны появляться в конце объявления - PullRequest
17 голосов
/ 24 мая 2010

Во всех языках программирования, поддерживающих дополнительные параметры, которые я видел, есть имитация того, что дополнительные параметры должны появляться в конце объявления.Никакие обязательные параметры не могут быть включены после дополнительного элемента.В чем причина этого?Я думаю, это может быть требование компилятора / интерпретатора.

Ответы [ 6 ]

16 голосов
/ 24 мая 2010

Ну, если бы они были впереди, как бы вы узнали, когда они перестали поставляться? Единственный способ был бы, если бы тип переменной отличался после необязательных параметров. Немного странное требование, поэтому имеет смысл, что вы просто заставляете их быть последними (избавьте от сложных правил определения «окончательного» необязательного параметра).

Кроме того, это наиболее естественный способ сделать это при вызове функции.

6 голосов
/ 25 мая 2010

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

Отлично работает в 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)

Обязательные параметры в начале списка параметров связаны слева направо от начала списка параметров. Обязательные параметры в конце списка параметров связаны справа налево от конца списка аргументов. Необязательные параметры связаны слева направо от начала списка оставшихся аргументов. Все оставшиеся аргументы связаны с остальными аргументами.

3 голосов
/ 24 мая 2010

Рассмотрим объявление вроде:

int foo(float a, int b=0, int c=0, float d);

(обратите внимание, как я определил параметры по умолчанию в середине списка), которое впоследствии называется как

foo(0.0,1,2.0)

Что такоевызов?В частности, были ли пропущены b или c?

Разработчики компиляторов могут обойти это, используя именованные параметры

foo(a=0,c=0,d=2.0)

функция, например, доступная в python.

0 голосов
/ 24 мая 2010

Необязательные параметры в конце позволяют вам прекратить задавать параметры в какой-то момент, например,

void Test(int a, optional int b = 0, optional int c = 0) { ... } 

Test(3);

Если вы сделаете c обязательным параметром, вам придется использовать синтаксис, подобный следующему:

Test(3, , 2);
Test(a := 3, c := 2);

Преимущество необязательного параметра заключается в том, что его можно рассматривать так, как если бы его там не было . Если дополнительные параметры находятся в середине списка параметров, это невозможно без «подсчета запятых» или использования слишком подробного синтаксиса.

0 голосов
/ 24 мая 2010

Java и C # не имеют именованных параметров, поэтому вы не можете сделать:

myfunction(param1='Meh', optionalParam=2)

Вы должны сделать:

myfunction('Meh', 2)

В противном случае

myFunction(2, 'Meh')

является неоднозначным.Как компилятор должен знать, что вы имели в виду 2, чтобы быть в наборе необязательных параметров?

0 голосов
/ 24 мая 2010

Просто гадание в дикой природе: возможно, это как-то связано с соглашениями о вызовах (например, параметры помещаются в стек слева направо, дополнительные параметры просто опускаются, если они не были указаны).

...