(delphi11最新学习资料) Object Pascal 学习笔记---第4章第2.6节(默认参数)
4.2.6 默认参数
与重载相关的另一个特性是可以为函数的某些参数提供默认值,这样就可以在调用函数时可使用或不使用这些参数。如果调用中缺少参数,函数将使用默认值。
让我举一个例子(仍然是 OverloadTest 示例的一部分)。我们可以定义以下 Show 调用的封装,提供两个默认参数:
procedure NewMessage(Msg: string; Caption: string = 'Message'; Separator: string = ': ');
begin
Show(Caption + Separator + Msg);
end;
有了这个定义,我们可以以以下方式调用该过程:
NewMessage('Something wrong here!');
NewMessage('Something wrong here!', 'Attention');
NewMessage('Hello', 'Message', '--');
输出如下:
Message: Something wrong here!
Attention: Something wrong here!
Message--Hello
请注意,编译器不会生成任何特殊代码来支持默认参数;它也不会创建多个(重载的)函数或过程的副本。缺少的参数只是由编译器添加到调用代码中。有一个影响默认参数使用的重要限制:您不能“跳过”参数。例如,您不能在省略第二个参数后将第三个参数传递给函数。
请注意,编译器不会生成支持默认参数的任何特殊代码,也不会创建函数或过程的多个(重载)副本。编译器只是将缺失的参数添加到调用代码中。使用默认参数有一个重要的限制: 不能 "跳过"参数。例如,在省略第二个参数后,不能将第三个参数传递给函数。
在定义和调用带缺省参数的函数和过程(以及方法)时,还有其他一些规则:
- 在例程的调用中,只能从最后一个参数开始省略参数。换句话说,如果省略了一个参数,就必须同时省略后面的参数。
- 在例程的定义中,带缺省值的参数必须放在参数列表的末尾。
- 默认值必须是常量。显然,这限制了默认参数的使用类型。例如,动态数组或接口类型不能使用 nil 以外的默认参数,也不能使用记录。
- 带有默认值的参数必须以值或 const 的形式传递。引用(var)参数不能有默认值。
同时使用缺省参数和重载,更有可能使编译器感到困惑,从而引发歧义调用错误,如上一节所述。例如,如果我在前面的示例中添加以下新版本的过程 NewMessage:
procedure NewMessage(Str: string; I: Integer = 0); overload;
begin
Show(Str + ': ' + IntToStr(I))
end;
编译器不会报错,因为这是一个合法的定义。然而,如果您写下以下调用:
NewMessage('Hello');
这将被编译器标记为:
[dcc32 Error] E2251 Ambiguous overloaded call to 'NewMessage'
Related method: procedure NewMessage(string; string; string);
Related method: procedure NewMessage(string; Integer);
请注意,这个错误出现在新的重载定义之前能够编译正确的一行代码中。实际上,我们无法调用只有一个字符串参数的过程 NewMessage
,因为编译器不知道我们是要调用只有字符串参数的版本,还是要调用有字符串参数和带有默认值的整数参数的版本。当编译器无法确定时,编译器就会停止,并通知程序员更清楚地表达自己的意图。