代码之家  ›  专栏  ›  技术社区  ›  Peter Perháč

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

  •  31
  • Peter Perháč  · 技术社区  · 14 年前

    我认为我的手离德尔菲太久了,我想,在过去的几年里,我一直忙于使用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;
    

    一个简单的地方

    result := result + (combo.text='')?'null':quotedStr(combo.text);
    

    就够了。我喜欢的是它不仅缩短了代码,而且避免了声明一些助手 s:string 变量。

    为什么条件运算符不是Delphi的一部分,并且-它们是否会被支持?我注意到有相当多的语言扩展是为2009年的Delphi(Generics)版本所做的,那么为什么不添加这个特性呢?

    10 回复  |  直到 10 年前
        1
  •  40
  •   Rob Kennedy dkackman    14 年前

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

    Delphi提供了一组 IfThen Math和Strutils单元中的函数,但它们具有评估两个值参数的不幸属性,因此类似这样的代码将失败:

    Foo := IfThen(Obj = nil, '<none>', Obj.Name);
    

    要真正做到正确,需要编译器的帮助。在Delphi社区中,我普遍不喜欢使用问号和冒号的C样式语法。我看到过使用如下语法的建议:

    Foo := if Obj = nil then
             '<none>'
           else
             Obj.Name;
    

    条件运算符之所以如此吸引人,部分原因是它们允许您编写简洁的代码,但Delphi的所有内容都采用这种编写方式,即使将所有内容都放在一行上,也会使上述内容不具吸引力。

    它不需要以 操作人员 . Delphi Prism提供编译器的魔力函数 Iif 它只计算其两个值参数之一:

    Foo := Iif(Obj = nil, '<none>', Obj.Name);
    

    您问过为什么像这样的功能不会和Delphi2009中添加的所有其他语言功能一起添加。我想这就是你的原因。还有很多其他的语言变化已经需要精细的处理;开发人员不需要承担更多的负担。功能不是免费的。

    你问德尔福是否会有这样的功能。我不知道Embarcadero的计划会议,我不得不把我的水晶球送去修理,所以我不能肯定,但我预测如果它曾经 有了这样一个特性,它将以德尔菲棱镜的形式出现。 IIF 功能。这个想法出现在 the discussion in Quality Central ,并提出了一个反对意见,即作为一个新的保留字,它将打破与已经定义了同名函数的其他人的代码的向后兼容性。不过,这不是一个有效的对象,因为它不需要是保留字。它可以是一个标识符,就像 Writeln Exit 即使对来自系统单元的单元进行了特殊处理,也可以在其他单元中重新定义它。

        2
  •  5
  •   glob    14 年前

    有质量控制报告( 8451 )有一个合理的讨论。

    2004年6月,Borland/Codegear/Embarcadero似乎没有任何回应。

        3
  •  5
  •   Wouter van Nifterick Andrey    13 年前

    好啊。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.
    

    是的,它或多或少是无用的,但它表明它是可以做到的。

        4
  •  5
  •   bluish dmajkic    12 年前

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

    StrUtils.IfThen ( String )

    Math.IfThen ( Integer )

    数学.ifthen ( Int64 )

    马蒂夫 ( Double (作品) TDateTime 同样)

    这个模型如Andreas所评论的示例中所示下降,但对于简单的类型,这是非常合理的。如果遵循delphi/pascal方法惯例,而不是屈从于使用尽可能少的字符量的C方法。

    我个人不希望看到条件运算符(即 ?: )在Delphi中介绍,因为我更喜欢Delphi/Pascal的可读性,而不是C和IT派生语言。我更愿意看到更多的Delphi类型的解决方案来解决类似的问题,而不是实现更多的C-ISMS。

        5
  •  4
  •   Ether    14 年前

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

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

    function Iff(const ACondition: Boolean; const ATrueValue, AFalseValue: XXX): XXX;
    begin
      if ACondition then
        Result := ATrueValue
      else
        Result := AFalseValue;
    end;
    

    其中,xxx是desirec类型。

    用作:

    Result := Result + Iff(combo.text='', 'null', quotedStr(combo.text));
    

    为什么不实现条件运算符有几个原因。其中之一是可读性。Pascal(以及Delphi)比C语法语言更注重可读性,后者更注重字符能力(尽可能多地了解每个字符的信息)。条件运算符功能强大,但(根据某些内容)不可读。但如果你看看德尔菲的(恐惧)陈述…(不用多说了)。 另一个原因是不需要条件运算符。这是真的。但是,还有更多的不需要实现的内容。

    最后,这只是一个品味问题。

    但是,如果您只想评估一个参数,则可以始终使用以下参数,这违反了字符幂概念的可读性:

    [过度设计模式]

    // 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;
    

    [/过度设计模式]

        6
  •  3
  •   Pham    14 年前

    我希望他们能够实现懒惰的评估,它将更加强大,可以在不同的场景中使用。详情见以下链接

    http://www.digitalmars.com/d/2.0/lazy-evaluation.html

    干杯

        7
  •  1
  •   Fabio Gomes    14 年前

    实际上,对于字符串,可以使用: 斯特劳斯 功能:

    function IfThen(AValue: Boolean;
            const ATrue: string;
            AFalse: string = ): string; overload;
    

    查看Delphi帮助维基: http://docwiki.embarcadero.com/VCL/en/StrUtils.IfThen

    它完全满足你的需要。

        8
  •  1
  •   TmTron    10 年前

    另一种选择是使用泛型:

    Cond<T> = class
        public class function IIF(Cond: boolean; IfVal: T; ElseVal: T): T;
      end;
    
    implementation
    
    class function Cond<T>.IIF(Cond: boolean; IfVal, ElseVal: T): T;
    begin
      if Cond then
        Result := IfVal
      else
        Result := ElseVal;
    end;
    

    这是非常可读的:

    var MyInt: Integer;
    begin
      MyInt:= Cond<Integer>.IIF(someCondition, 0, 42);
    

    注:如Alan Bryant(2004年6月21日上午7:26:21)在 QR 8451 ,这将始终评估所有3个参数-因此请注意,它不是真正的三元运算符。

        9
  •  0
  •   General Jackson Tackett    14 年前

    更好的是,支持多个数据类型和结果的重载IIF(inline if)。

        10
  •  0
  •   iluwatar    13 年前

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

    http://wiki.delphi-jedi.org/wiki/JCL_Help:Iff@Boolean@Boolean@Boolean

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

    http://sourceforge.net/projects/jcl/

    推荐文章