【问题标题】:Named/optional parameters in Delphi?Delphi中的命名/可选参数?
【发布时间】:2010-10-27 12:31:52
【问题描述】:

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

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

Docs.Add(NewTemplate := True); // note the assignment

我似乎无法在我自己的代码中重现这种类型的参数传递,而且我从未见过有人使用它。所以这些是我的问题:

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

  • 需要什么才能使用它?

  • 这是否类似于 C#4 的命名参数和可选参数?


附加信息:我通常通过 有记录或简单的类 有许多可选参数 方法,但看起来我不会 需要这种语法。我意识到 默认参数值,但它们的 有用性是有限的,因为你 不能提供任何参数给 一个省略的权利。在 JavaScript 中 我正在使用这个命名参数样式 一直(无论是不同的 语法),而且它很强大。

【问题讨论】:

  • 通过命名传递参数的特性是OLE的特性,而不是Delphi的特性。不要浪费时间在德里实现此功能。

标签: delphi optional-parameters named-parameters


【解决方案1】:

很明显,Delphi 语言支持命名参数,因为它们出现在 Delphi 示例代码中。 Delphi 支持自动化对象上的命名参数,这些对象是实现IDispatch 接口的对象。 There are restrictions on the types the parameters and return types can have;特别是,它们不能是 Delphi 类。

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

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

我认为可选参数被高估了。它们为(一个)编写代码的人节省了时间,但没有为(许多)阅读代码的人节省时间。阅读它的人都需要知道任何未指定参数的默认值是什么,因此您最好还是明确地提供所有值。

【讨论】:

  • 我想要它们:你可以调用一个函数说“我想要完全的默认行为,除了 this 一件事。”读者会立即明白你的意图。就像现在一样,您必须扫描对函数的大量调用,它们与默认参数匹配以及它们的不同之处。
  • 我同意乌尔里希的观点。从我使用 Ruby 开始,能够指定命名参数非常方便,尤其是对于可能有很多参数并且您只关心几个参数的函数。它们还增加了代码的可读性,因为您无需知道参数调用顺序即可了解每个参数的用途。
  • 我喜欢使用它们。而不是 CallProc(1, 2, 3) 我可以阅读 CallProc(TimesToLoop := 1, MagicValue := 2, PossibleReturnCode := 3)
  • 还有一个问题 - 参数名称与关键字冲突,例如参数名为“end”
  • 我认为你可以use & to escape the keywords,@Arioch。
【解决方案2】:

它基本上是“自动化对象的一些编译器破解”。我有时不得不将它用于 Excel 和 Word 自动化。

例如

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

相当于VBA

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

【讨论】:

    【解决方案3】:

    如果你这样声明你的程序:

    procedure DoSomething(AParam : integer = 0);
    

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

    procedure DoSomething(AFirstParam : string; AParam : integer = 0);
    

    不是这样的:

    procedure DoSomething(AParam : integer = 0; ASecondParam : string);
    

    【讨论】:

      猜你喜欢
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 2019-04-14
      • 2018-08-11
      • 1970-01-01
      相关资源
      最近更新 更多