Delphi中的命名/可选参数?

Wou*_*ick 12 delphi optional-parameters named-parameters

在其中一个Delphi演示应用程序中,我偶然发现了一些我不知道Delphi编译器接受的语法:

// ......\Demos\DelphiWin32\VCLWin32\ActiveX\OleAuto\SrvComp\Word\    
// Main.pas, line 109

Docs.Add(NewTemplate := True); // note the assignment
Run Code Online (Sandbox Code Playgroud)

我似乎无法重现这种类型的参数传递我自己的代码,我从来没有看到任何人使用它.所以这些是我的问题:

  • 我可以在"普通"方法中使用它,它是"Delphi语言"的一部分,还是一些编译器破解自动化对象?

  • 为了能够使用它需要什么?

  • 这有点像C#4的命名和可选参数吗?


附加信息:当方法有许多可选参数时,我通常会传递记录或简单类,但看起来我不需要使用这种语法.我知道默认参数值,但它们的用处是有限的,因为你不能在省略的参数值的右边提供任何参数.在JavaScript中,我一直在使用这个命名参数样式(使用不同的语法),并且功能强大.

Rob*_*edy 19

很明显,Delphi语言支持命名参数,因为它们出现在Delphi代码示例中.Delphi支持自动化对象上的命名参数,自动化对象是实现IDispatch接口的对象.参数和返回类型可以有类型的限制 ; 特别是,它们不能是Delphi类.

我不认为你从命名参数中寻求的便利性会超过你通过该IDispatch.Invoke方法路由每个方法调用所带来的性能.呼叫也可能需要先使用GetIDsOfNames.你没有在更多的代码中看到这一点,因为后期绑定通常是人们试图避免的.尽可能使用早期绑定,以避免查找调度ID和间接方法调用的成本.

Delphi通过允许默认值支持非自动化代码中的可选参数.只要您还省略所有后续参数的实际参数,您就可以省略具有默认值的任何参数的实际参数 - 编译器确保函数的声明允许这样做.

我认为可选参数被高估了.它们为(一)人编写代码节省了时间,但对于(很多)人阅读代码却没有.无论谁在阅读它,都需要知道任何未指定参数的默认值是什么,所以你也可以只是明确地提供所有值.

  • 我同意乌尔里希的观点.从我使用Ruby的时间开始,能够指定命名参数非常方便,特别是对于可能包含许多参数且只关心一对的函数.它们还增加了代码的可读性,因为您不需要知道参数调用顺序来了解每个参数的用途. (4认同)
  • 我喜欢他们:你可以打电话给一个函数说"我想要除了***之外的确切的默认行为." 读者会马上得到你的意图.现在你必须扫描大量的函数调用,它们匹配默认参数和它们的不同之处. (2认同)
  • 我喜欢用它们.而不是CallProc(1,2,3)我可以读取CallProc(TimesToLoop:= 1,MagicValue:= 2,PossibleReturnCode:= 3) (2认同)
  • 我假设你可以[使用“&”来转义关键字](http://stackoverflow.com/a/424107/33732),@Arioch。 (2认同)

Tim*_*van 6

如果您这样声明程序:

procedure DoSomething(AParam : integer = 0);
Run Code Online (Sandbox Code Playgroud)

...如果未指定参数,它将假定参数值为0。我记得,带有默认值的参数必须在调用的结尾,所以像这样:

procedure DoSomething(AFirstParam : string; AParam : integer = 0);
Run Code Online (Sandbox Code Playgroud)

不像这样:

procedure DoSomething(AParam : integer = 0; ASecondParam : string);
Run Code Online (Sandbox Code Playgroud)


Ger*_*oll 5

它基本上是“一些针对自动化对象的编译器黑客”。有时我必须使用它来实现 Excel 和 Word 自动化。

例如

  MSExcel.Application.Cells.Replace(What:='', Replacement:='', LookAt:=xlPart,
    SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=True, ReplaceFormat:=True);
Run Code Online (Sandbox Code Playgroud)

相当于VBA

Application.Cells.Replace(What='', Replacement='', LookAt=xlPart, _
   SearchOrder=xlByRows, MatchCase=False, SearchFormat=True, ReplaceFormat=True)
Run Code Online (Sandbox Code Playgroud)