Delphi中有条件运算符,或者有没有?

Pet*_*háč 32 delphi language-features delphi-2009 conditional-operator

我想,我把手远离德尔福太久了.在过去的几年里,我一直忙于Java和PHP.现在,当我回到做一点Delphi工作时,我意识到我真的很想念Java和PHP都支持的条件运算符.

在Delphi程序中你会找到多少个这样的行?

var s : string;
begin
  ...<here the string result is manipulated>...

  if combo.Text='' then
      s := 'null'
    else
      s := QuotedStr(combo.Text);

  result := result + s;
end;
Run Code Online (Sandbox Code Playgroud)

哪里很简单

result := result + (combo.text='')?'null':quotedStr(combo.text);
Run Code Online (Sandbox Code Playgroud)

就够了 我喜欢这个,它不仅缩短了代码,这样我也避免声明一些辅助s:string变量.

为什么条件运算符不是Delphi的一部分 - 它们是否会得到支持?我注意到2009版Delphi(泛型)有很多语言扩展,为什么不添加这个功能呢?

Rob*_*edy 41

这样的运算符不是当前Delphi版本的一部分,因为它不是以前版本的一部分,并且需求不足以证明添加它的成本是合理的.(你会发现,解释适用于很多的功能,你希望你有很多的产品.)

Delphi IfThen在Math和StrUtils单元中提供了一组函数,但它们具有评估它们的值参数的不幸特性,因此像这样的代码将失败:

Foo := IfThen(Obj = nil, '<none>', Obj.Name);
Run Code Online (Sandbox Code Playgroud)

要真正做到正确,需要得到编译器的帮助.在Delphi社区中,我感觉到使用问号和冒号一般不喜欢C风格的语法.我见过会使用如下语法的提案:

Foo := if Obj = nil then
         '<none>'
       else
         Obj.Name;
Run Code Online (Sandbox Code Playgroud)

使条件运算符如此具有吸引力的部分原因在于它们可以让您编写简洁的代码,但是Delphi将所有内容写出来的风格使得上述内容无法实现,即使将所有内容放在一行上也是如此.

它实际上不需要以运算符的形式存在.Delphi Prism提供了一个编译器魔术函数Iif,它只评估其两个值参数之一:

Foo := Iif(Obj = nil, '<none>', Obj.Name);
Run Code Online (Sandbox Code Playgroud)

你问为什么这样的功能不会与Delphi 2009中添加的所有其他语言功能一起添加.我认为这是你的理由.还有许多其他的语言变化已经需要精细处理; 开发人员不需要承担更多的负担.功能不是免费的.

你问德尔福是否会有这样的功能.我并不了解Embarcadero公司的规划会议,我只好送我的水晶球离开了修理,所以我不能肯定地说,但我预测,如果它具有这样的功能,它会来的形式Delphi Prism的Iif功能.这个想法在Quality Central的讨论结束时出现,并且反对意见是,作为一个新的保留字,它会破坏与已定义具有相同名称的函数的其他人的代码的向后兼容性.但是,这不是一个有效的对象,因为它不需要是一个保留字.它可以是一个标识符,就像WritelnExit,即使系统单元中的一个是专门处理的,也可以在其他单元中重新定义.

  • 这种语法效果是否被归类为"好看"或"优雅"是一个有争议的问题,@ PA.我发现你的例子是一个不可思议的代码.我在第一次阅读时无法理解 - 我甚至无法在一遍中解析它.空格和括号可能会有所帮助.我尽量避免使用嵌套的条件运算符. (6认同)
  • @RobKennedy我在说垃圾。编译器的内联函数确保始终评估可能有副作用的任何参数。编译器编写代码以对其进行评估,然后将其存储在堆栈框架中。显然,这样做是为了避免内联选择引起的语义变化。如果表达式不能有副作用,则可以根据需要对其进行评估。 (3认同)
  • @PA 我和 Rob 在一起。如果它使代码更难以理解,我不会称其为优雅。我会将您的示例描述为对比较运算符的过度使用(滥用)。不过,这对于 [Obfuscated C Code Contest](http://www.ioccc.org) 来说是一种有用的技术。 (2认同)
  • `If​​Then` 的现代 Delphi 实现是内联的,因此只评估所选选项 (2认同)

glo*_*lob 5

关于此(8451)的QC报告有一个合理的讨论.

2004年6月提出,Borland/CodeGear/Embarcadero似乎没有任何回应.


Rya*_*lls 5

重载的IFTHEN函数有许多可用的简单类型句柄.

StrUtils.IfThen(String)

Math.IfThen(Integer)

Math.IfThen(Int64)

Math.IfThen(Double)(TDateTime同样适用)

这个模型如Andreas所评论的示例所示,但对于简单类型,这是非常合理的.如果遵循Delphi/Pascal方法的约定而不是屈服于使用尽可能少的字符的C方式.

就个人而言,我宁愿看不到?:Delphi中引入的条件运算符(即),因为我更喜欢Delphi/Pascal对C及其派生语言的可读性.我希望看到更多创新的Delphi类型解决方案,而不是实现更多的C-isms.


Wou*_*ick 5

好.当天的WTF代码:)

如何获得主要像三元/条件函数的东西.

program Project107;
{$APPTYPE CONSOLE}

uses SysUtils;

type
  TLazyIfThen<T:record>=record
    class function IfThen(aCondition:Boolean;aIfTrue, aIfFalse:TFunc<T>):T; static;
  end;

  class function TLazyIfThen<T>.IfThen(aCondition:Boolean;aIfTrue, aIfFalse:TFunc<T>):T;
  begin
    if aCondition then
      Result := aIfTrue
    else
      Result := aIfFalse
  end;

begin
  WriteLn(
    TLazyIfThen<Integer>.IfThen(
      True,
      function:Integer begin result := 0 end,
      function:Integer begin result := 1 end
    )
  );
  ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)

是的,它或多或少都没用,但它表明它可以完成.

  • 呵呵......德尔福从未在这里的代码 - 高尔夫比赛中成为真正的赢家. (3认同)