Delphi中是否存在或将来是否会存在条件运算符?

Delphi中是否存在或将来是否会存在条件运算符?,delphi,delphi-2009,language-features,conditional-operator,Delphi,Delphi 2009,Language Features,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 := Quo

我想我的手离德尔福太久了;在过去的几年里,我一直忙于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;
就够了。我喜欢的是它不仅缩短了代码,这样我也避免了声明一些helper
s:string
变量


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

Delphi中没有条件运算符,我严重怀疑是否会有条件运算符,但您可能永远不知道。您可以随时在Embarcadero发出请求

另一种方法是定义Iff函数:

function Iff(const ACondition: Boolean; const ATrueValue, AFalseValue: XXX): XXX;
begin
  if ACondition then
    Result := ATrueValue
  else
    Result := AFalseValue;
end;
function IfThen(AValue: Boolean;
        const ATrue: string;
        AFalse: string = ): string; overload;
其中XXX是desirec类型

用作:

Result := Result + Iff(combo.text='', 'null', quotedStr(combo.text));
为什么不实现条件运算符有几个原因。其中之一就是可读性。Pascal(还有Delphi)比C语法语言更注重可读性,C语法语言更注重字符能力(每个字符尽可能多的信息)。条件运算符功能强大,但(根据某些人的说法)不可读。但是如果你看看Delphi中的(可怕的)with语句。。。(无需多说)。 另一个原因是不需要条件运算符。这是真的。但是,还有更多不需要的东西仍在实施

最后,这只是口味的问题

但是,如果您只想计算一个参数,则始终可以使用以下参数,这违反了可读性和角色能力的概念:

[过度设计模式]

// Please don't take this that serious.
type
  TFunc = function(): XXX;
function Iff(const ACondition: Boolean; const ATrueFunc, AFalseFunc: TFunc): XXX;
begin
  if ACondition then
    ATrueFunc
  else
    AFalseFunc;
end;

[/overdesignmode]

有一份关于这个()的QC报告,其中有一个合理的讨论

// Please don't take this that serious.
type
  TFunc = function(): XXX;
function Iff(const ACondition: Boolean; const ATrueFunc, AFalseFunc: TFunc): XXX;
begin
  if ACondition then
    ATrueFunc
  else
    AFalseFunc;
end;

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

实际上,对于字符串,您可以使用:StrUtils。如果函数:

function Iff(const ACondition: Boolean; const ATrueValue, AFalseValue: XXX): XXX;
begin
  if ACondition then
    Result := ATrueValue
  else
    Result := AFalseValue;
end;
function IfThen(AValue: Boolean;
        const ATrue: string;
        AFalse: string = ): string; overload;
查看delphi帮助wiki:


它完全满足您的需要。

这样的操作符不是当前Delphi版本的一部分,因为它不是以前版本的一部分,而且需求量也不足以证明添加它的成本。(你会发现这种解释适用于你希望在很多产品中拥有的许多功能。)

Delphi提供了一组以Math和StrUtils为单位的
函数,但它们的不幸特性是同时计算它们的值参数,因此这样的代码将失败:

Foo := IfThen(Obj = nil, '<none>', Obj.Name);
您曾问,为什么像这样的特性不会与Delphi2009中添加的所有其他语言特性一起添加。我想这就是你的理由。还有许多其他的语言变化正在进行,这些变化已经需要微妙的处理;开发者不需要承担更多的负担。功能不是免费的


你问Delphi是否会有这样的功能。我不知道Embarcadero的计划会议,我不得不把我的水晶球送去修理,所以我不能肯定,但我预测如果它有这样的功能,它将以Delphi Prism的
Iif
函数的形式出现。这个想法在接近结尾的时候出现了,有人反对说,作为一个新的保留字,它将破坏与其他人已经定义了同名函数的代码的向后兼容性。但这不是一个有效的对象,因为它不需要是保留字。它可以是一个标识符,就像
Writeln
Exit
一样,它可以在其他单元中重新定义,即使来自系统单元的单元经过特殊处理。

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

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.
stritils.IfThen
String

Math.IfThen
Integer

Math.IfThen
Int64

Math.IfThen
Double
)(也适用于
TDateTime

如Andreas所评论的示例所示,此模型已失效,但对于简单类型,这是非常合理的。If遵循Delphi/Pascal方法惯例,而不是屈服于使用尽可能少的字符的C方式


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

更好的是支持多种数据类型和结果的重载IIF(内联if)。

我更愿意他们实现延迟评估,它将更强大,可以在不同的场景中使用。请参见以下链接中的详细信息

Cheers

绝地代码库(JCL)用一组名为Iff()的函数实现了三元运算符。有关文档,请参见此处:

要下载JCL,您可以访问以下网站:

好的。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.
程序项目107;
{$APPTYPE控制台}
使用SysUtils;
类型
TLazyIfThen=记录
类函数IfThen(条件:Boolean;aIfTrue,aIfFalse:TFunc):T;静止的
结束;
类函数TLazyIfThen.IfThen(条件:Boolean;aIfTrue,aIfFalse:TFunc):T;
开始
如果是条件那么
结果:=aIfTrue
其他的
结果:=aIfFalse
结束;
开始
写(
特拉基夫滕(
是的,
函数:整数开始结果:=0结束,
函数:整数开始结果:=1结束
)
);
ReadLn;
结束。
是的,它或多或少是无用的,但它表明它可以是唐
var MyInt: Integer;
begin
  MyInt:= Cond<Integer>.IIF(someCondition, 0, 42);
program TernaryOpTest;

uses
  System.SysUtils, Vcl.Dialogs;

type
  TGetValue = reference to function(): Double;

function TernaryOp(condition: Boolean; trueFunc, falseFunc: TGetValue): Double;
begin
  if condition then begin
    if Assigned(trueFunc) then Result := trueFunc() else raise EArgumentNilException.Create('trueFunc not defined.');
  end
  else begin
    if Assigned(falseFunc) then Result := falseFunc() else raise EArgumentNilException.Create('falseFunc not defined.');
  end;
end;

procedure TernaryTest(x: Double);
var
  v: Double;
begin
  v := TernaryOp(x <> 0, function(): Double begin Result := 1/x; ShowMessage('True case'); end, function(): Double begin Result := 0; ShowMessage('False case'); end);
  ShowMessage(FloatToStr(v));
end;

begin
  ShowMessage('Testing true case');
  TernaryTest(10);
  ShowMessage('Testing false case');
  TernaryTest(0);
  ShowMessage('Testing exception');
  TernaryOp(False, nil, nil);
end.
type
  TGetValue = reference to function(): Variant;

function TernaryOp(condition: Boolean; trueFunc, falseFunc: TGetValue): Variant;
begin
  Result := Unassigned;
  if condition then begin
    if Assigned(trueFunc) then Result := trueFunc();
  end
  else begin
    if Assigned(falseFunc) then Result := falseFunc();
  end;
end;