为什么必须在声明末尾出现可选参数

时间:2021-10-20 08:47:03

In all programming languages supporting optional parameters that I have seen there is a imitation that the optional parameters must appear at the end of the declaration. No required parameters may be included after an optional item. What is the reason for that ? I guess it can be compiler/interpreter requirement.

在我看到的支持可选参数的所有编程语言中,都有一种模仿,即必须在声明末尾出现可选参数。在可选项之后不能包含任何必需的参数。原因是什么?我想这可能是编译器/解释器的要求。

6 个解决方案

#1


16  

Well, if they were at the front, how would you detect when they've stopped being supplied? The only way would be if the variable type was different after the optional parameters. Bit of a weird requirement, so it makes sense that you just force them to be last (save the trouble of complex rules for detecting the "final" optional parameter).

如果它们在前面,你怎么检测它们何时停止供应?唯一的方法是如果变量类型在可选参数之后是不同的。这是一个有点奇怪的需求,所以强制它们为last(省去了检测“final”可选参数的复杂规则的麻烦)是有意义的。

Besides, it's the most natural way to do it when calling the function.

此外,这是调用函数时最自然的方法。

#2


5  

This is just an arbitrary rule that the designers of those specific languages made. There is absolutely no technical reason why that restriction should be there.

这只是这些特定语言的设计人员所制定的任意规则。绝对没有技术上的原因来解释为什么会有这样的限制。

It works just fine in Ruby:

它在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]

All mandatory arguments must be supplied:

必须提供所有强制性的论点:

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

Without the rest parameter, supplying more than number_of_mandatory + number_of_optional arguments is an error:

如果没有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)

Mandatory parameters at the beginning of the parameter list are bound from left-to-right from the beginning of the argument list. Mandatory parameters at the end of the parameter list are bound from right-to-left from the end of the argument list. Optional parameters are bound left-to-right from the beginning of the remaining argument list. All arguments left over are bound to rest arguments.

参数列表开头的强制性参数从参数列表的开头从左到右绑定。参数列表末尾的强制性参数是从参数列表的末尾从右到左绑定的。可选参数从左到右从剩余的参数列表开始绑定。剩下的所有参数都必然是rest参数。

#3


2  

Consider a declaration like:

考虑一个声明:

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

(notice how I've defined defult parameters in the middle of the list) which is subsequently called like

(注意我如何在列表中间定义了defult参数),它随后被称为like

foo(0.0,1,2.0)

What is the call? In particular has b or c been omitted?

电话是什么?特别是b或c被省略了吗?

Compiler designers can get around this by using named parameters

编译器设计者可以通过使用命名参数来绕过这个问题

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

a feature available in python for instance.

例如,在python中可用的特性。

#4


0  

Just guessing in the wild: It maybe has something to do with calling conventions (e.g. parameters are pushed on the stack left to right, optional parameters are simply left out in case they were not specified).

随便猜测一下:它可能与调用约定有关(例如,参数被从左向右推到堆栈上,如果没有指定可选参数,那么可选参数就被省略了)。

#5


0  

Optional parameters at the end allow you to stop specifying parameters at some point, e.g.

最后的可选参数允许您在某些时候停止指定参数,例如。

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

Test(3);

If you make c a required parameter, you'd have to use syntaxes like this:

如果你将c作为一个必需的参数,你就必须使用这样的语法:

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

The advantage of an optional parameter is that it can be treated as if it wasn't there. If the optional parameters are in the middle of the parameter list, this is not possible without "counting commas" or using an overly verbose syntax.

可选参数的优点是可以将其视为不存在。如果可选参数位于参数列表的中间,则不可能不使用“计数逗号”或使用过于冗长的语法。

#6


-1  

Java and C# don't have named parameters so you can't do:

Java和c#没有命名参数,所以不能:

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

You have to do:

你要做的:

myfunction('Meh', 2)

Otherwise

否则

myFunction(2, 'Meh')

Is ambiguous. How is the compiler supposed to know that you meant 2 to be in the optional parameter set?

是模棱两可的。编译器怎么知道你的意思是2在可选参数集中?

#1


16  

Well, if they were at the front, how would you detect when they've stopped being supplied? The only way would be if the variable type was different after the optional parameters. Bit of a weird requirement, so it makes sense that you just force them to be last (save the trouble of complex rules for detecting the "final" optional parameter).

如果它们在前面,你怎么检测它们何时停止供应?唯一的方法是如果变量类型在可选参数之后是不同的。这是一个有点奇怪的需求,所以强制它们为last(省去了检测“final”可选参数的复杂规则的麻烦)是有意义的。

Besides, it's the most natural way to do it when calling the function.

此外,这是调用函数时最自然的方法。

#2


5  

This is just an arbitrary rule that the designers of those specific languages made. There is absolutely no technical reason why that restriction should be there.

这只是这些特定语言的设计人员所制定的任意规则。绝对没有技术上的原因来解释为什么会有这样的限制。

It works just fine in Ruby:

它在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]

All mandatory arguments must be supplied:

必须提供所有强制性的论点:

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

Without the rest parameter, supplying more than number_of_mandatory + number_of_optional arguments is an error:

如果没有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)

Mandatory parameters at the beginning of the parameter list are bound from left-to-right from the beginning of the argument list. Mandatory parameters at the end of the parameter list are bound from right-to-left from the end of the argument list. Optional parameters are bound left-to-right from the beginning of the remaining argument list. All arguments left over are bound to rest arguments.

参数列表开头的强制性参数从参数列表的开头从左到右绑定。参数列表末尾的强制性参数是从参数列表的末尾从右到左绑定的。可选参数从左到右从剩余的参数列表开始绑定。剩下的所有参数都必然是rest参数。

#3


2  

Consider a declaration like:

考虑一个声明:

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

(notice how I've defined defult parameters in the middle of the list) which is subsequently called like

(注意我如何在列表中间定义了defult参数),它随后被称为like

foo(0.0,1,2.0)

What is the call? In particular has b or c been omitted?

电话是什么?特别是b或c被省略了吗?

Compiler designers can get around this by using named parameters

编译器设计者可以通过使用命名参数来绕过这个问题

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

a feature available in python for instance.

例如,在python中可用的特性。

#4


0  

Just guessing in the wild: It maybe has something to do with calling conventions (e.g. parameters are pushed on the stack left to right, optional parameters are simply left out in case they were not specified).

随便猜测一下:它可能与调用约定有关(例如,参数被从左向右推到堆栈上,如果没有指定可选参数,那么可选参数就被省略了)。

#5


0  

Optional parameters at the end allow you to stop specifying parameters at some point, e.g.

最后的可选参数允许您在某些时候停止指定参数,例如。

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

Test(3);

If you make c a required parameter, you'd have to use syntaxes like this:

如果你将c作为一个必需的参数,你就必须使用这样的语法:

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

The advantage of an optional parameter is that it can be treated as if it wasn't there. If the optional parameters are in the middle of the parameter list, this is not possible without "counting commas" or using an overly verbose syntax.

可选参数的优点是可以将其视为不存在。如果可选参数位于参数列表的中间,则不可能不使用“计数逗号”或使用过于冗长的语法。

#6


-1  

Java and C# don't have named parameters so you can't do:

Java和c#没有命名参数,所以不能:

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

You have to do:

你要做的:

myfunction('Meh', 2)

Otherwise

否则

myFunction(2, 'Meh')

Is ambiguous. How is the compiler supposed to know that you meant 2 to be in the optional parameter set?

是模棱两可的。编译器怎么知道你的意思是2在可选参数集中?