15

En todos los lenguajes de programación compatibles con los parámetros opcionales que he visto, existe una imitación de que los parámetros opcionales deben aparecer al final de la declaración. No se pueden incluir parámetros necesarios después de un artículo opcional. ¿Cuál es la razón para eso? Supongo que puede ser requisito de compilador/intérprete.Por qué los parámetros opcionales deben aparecer al final de la declaración

Respuesta

16

Bueno, si estuvieran en la parte delantera, ¿cómo detectarían cuándo han dejado de suministrarse? La única forma sería si el tipo de variable fuera diferente después de los parámetros opcionales. Es un requisito extraño, por lo que tiene sentido que los obligue a ser los últimos (guarde el problema de las reglas complejas para detectar el parámetro opcional "final").

Además, es la forma más natural de hacerlo al llamar a la función.

+0

Sí, parece tan obvio ahora :). Gracias. – Incognito

+0

@Incognito: funciona bien en Ruby. Si hay parámetros obligatorios después de los opcionales, entonces los argumentos obligatorios se toman del final de la lista de argumentos. Todo lo que sobra son los argumentos opcionales. Consulte http://StackOverflow.Com/questions/2896106/why-optional-parameters-must-appear-at-the-end-of-the-declaration/2900474/#2900474 para ver un ejemplo. –

0

Simplemente adivinando en la naturaleza: Quizás tenga algo que ver con las convenciones de llamadas (por ejemplo, los parámetros se colocan en la pila de izquierda a derecha, los parámetros opcionales simplemente se dejan en caso de que no se especifiquen).

+1

Lo dudo, creo que la persona que llama simplemente presionará los valores predeterminados. – tstenner

-1

Java y C# no han nombrado los parámetros por lo que no puede hacer:

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

que tiene que hacer:

myfunction('Meh', 2) 

De lo contrario

myFunction(2, 'Meh') 

es ambigua. ¿Cómo se supone que el compilador sabe que quería decir que 2 está en el conjunto de parámetros opcionales?

+7

C# 4.0 tiene parámetros nombrados. – Incognito

0

Los parámetros opcionales al final le permiten dejar de especificar parámetros en algún punto, p.

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

Test(3); 

Si haces c un parámetro necesario, habría que utilizar la sintaxis como esta:

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

La ventaja de un parámetro opcional es que puede ser tratado como si que no era' Hay. Si los parámetros opcionales están en el medio de la lista de parámetros, esto no es posible sin "contar comas" o usar una sintaxis demasiado detallada.

+1

Esto funciona bien en Ruby. Los parámetros obligatorios al principio de la lista de parámetros están limitados de izquierda a derecha desde el comienzo de la lista de argumentos. Los parámetros obligatorios al final de la lista de parámetros están vinculados de derecha a izquierda desde el final de la lista de argumentos. Los parámetros opcionales están enlazados de izquierda a derecha desde el principio de la lista de argumentos restantes. Todos los argumentos sobrantes están destinados a argumentos de descanso. No proporcionar un argumento obligatorio o suministrar más que argumentos 'num_mandatory + num_optional' cuando no hay parámetro de reposo es un error. –

2

Considérese una declaración como:

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

(note como he definido parámetros defult en el medio de la lista) que posteriormente se llamó como

foo(0.0,1,2.0) 

¿Cuál es la llamada? En particular, ¿se ha omitido b o c?

diseñadores compilador puede evitar esto mediante el uso de parámetros con nombre

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

una función disponible en Python, por ejemplo.

+1

Esa función también está disponible en C#: foo (a: 0, c: 0, d: 2.0). El problema es qué hacer cuando se realizan llamadas posicionales. – configurator

+2

Esto funciona bien en Ruby. Los parámetros obligatorios al principio de la lista de parámetros están limitados de izquierda a derecha desde el comienzo de la lista de argumentos. Los parámetros obligatorios al final de la lista de parámetros están vinculados de derecha a izquierda desde el final de la lista de argumentos. Los parámetros opcionales están enlazados de izquierda a derecha desde el principio de la lista de argumentos restantes. Todos los argumentos sobrantes están destinados a argumentos de descanso. No proporcionar un argumento obligatorio o suministrar más que argumentos 'num_mandatory + num_optional' cuando no hay parámetro de reposo es un error. –

+0

En su ejemplo específico, 'a' estaría obligado a' 0.0', 'd' a' 2.0', 'b' a' 1' y 'c' obtendría su valor predeterminado de' 0'. –

5

Esta es solo una regla arbitraria que los diseñadores de esos lenguajes específicos hicieron.No hay absolutamente ninguna razón técnica por la cual esa restricción debería estar allí.

Funciona muy bien en 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] 

Todos los argumentos obligatorios deben ser suministrados:

foo(1, 2, 3) 
# => ArgumentError: wrong number of arguments (3 for 4) 

Sin el parámetro de descanso, el suministro de más de number_of_mandatory + argumentos number_of_optional es un error:

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) 

Parámetros obligatorios al comienzo de la parame ter lista están limitados de izquierda a derecha desde el comienzo de la lista de argumentos. Los parámetros obligatorios al final de la lista de parámetros están vinculados de derecha a izquierda desde el final de la lista de argumentos. Los parámetros opcionales están enlazados de izquierda a derecha desde el principio de la lista de argumentos restantes. Todos los argumentos sobrantes están destinados a argumentos de descanso.

+0

Obviamente correcto --- cuanto más tenga un ejemplo de trabajo para mostrar. Pero voy a objetar en la medida en que los lenguajes tipo c se construyen principalmente a partir de reglas simples, y el camino de rubí es largo: sería una gran sorpresa en c, y al menos una pequeña en C++. – dmckee

+0

@dmckee: El único lenguaje tipo C que conozco que tiene argumentos opcionales sería C#, pero sus reglas son enormemente complicadas debido a interacciones complejas entre argumentos opcionales y sobrecarga basada en arity. Los encuentro a ambos * al menos * similarmente complicados, tal vez C# incluso un poco más. –

Cuestiones relacionadas