【问题标题】:Can one initialize multiple variables of some type in one line?可以在一行中初始化多个某种类型的变量吗?
【发布时间】:2014-06-12 20:48:23
【问题描述】:

我一直在尝试编写尽可能少的代码。 所以,我使用:

MyBoolean := Memo1.Text <> '';

而不是

if Memo1.Text = '' then
  MyBoolean := true
else
  MyBoolean := false;

声明和初始化

var
  myGlobal: integer = 99;

声明和初始化全局变量。我想对局部变量做同样的事情,但似乎不可能,所以,我想知道是否有一种方法可以在一行中初始化多个某种类型的变量,比如在 C 中

int x, y, z;
x=y=z=0;

谢谢。

【问题讨论】:

  • 嗯,是的,也不是。是的,例如写作X: Integer = 99; Y: Integer = 99; 在一行中,对多个赋值语句没有。
  • 如果你使用 Ctrl+D(又名代码格式化),那一行就不算多。
  • 是的,但是没有办法在单个语句中初始化多个变量。我很高兴是这样,因为像x=y=z=0 这样的声明对我来说很难阅读。就个人而言,我什至会写多行。
  • Edjis,我钦佩你对 DRY 的承诺(不要重复你自己)。不幸的是,Delphi 倾向于采用 WET 的形式(我们喜欢打字或写两次)。该语言没有实现许多可以减少重复代码的语法糖,例如三元运算符:x if a else c、多重赋值、更好的运算符优先级(以避免在带有布尔运算符的语句中需要括号)、幂运算符、for循环中的单步执行、case语句中的字符串、切片表示法、类型推断等。我希望一旦他们迁移到新的编译器,我们就能得到一些这样的东西。
  • @alcalde,为什么?我不知道。也许是因为当我阅读某些东西时,我的大脑通常不太关注表达中间的内容。所以,也许我害怕我在阅读时会丢失那些yz 变量,我不知道。关于临时变量,它们有什么问题?我宁愿清楚地看到所写的内容,也不会害怕额外的作业。此外,在生成的汇编代码中也是一样的。还是您认为有一条指令可以一次将函数的返回值分配给三个变量?

标签: delphi variables initialization


【解决方案1】:

在 C 中赋值是一个表达式(返回一个值)。

在 Pascal 中赋值是一个语句(不返回值)。

这种差异会产生一些有趣的后果。例如在C两者中

while (x=0)

while (x==0)

在 Pascal 中是语法上有效的结构(它是无数错误的根源)

while (x:=0)

在语法上无效,因为x:=0 是一个语句

【讨论】:

  • 我完全不明白这与问题有什么关系。问题是关于一次初始化多个变量。在 Python 中,赋值是一个语句,你不能像 Pascal 那样在 while 循环中分配一个变量。但是,x=y=z=0 也是一个有效的陈述。这两个概念之间绝对没有关系。
  • @alcalde 我对 Python 不够熟悉,无法了解该语言的意图,但相关性可能取决于您如何看待它的赋值功能:(1) 是赋值被视为带有语法盐的表达式以防止常见错误(如在while循环中)? (2) 还是将其视为带有语法糖的语句以简化多个值的分配? ...就更好地理解语言之间的差异而言,我个人认为答案非常相关和有趣。
【解决方案2】:

每个语句只能初始化一个局部变量。

【讨论】:

    【解决方案3】:

    当然可以写一个函数

    function AssignInteger(var _AssignTo: integer; _Value: integer): integer;
    begin
      Result := _Value;
      _AssignTo := _Value;
    end;
    

    并像这样使用它:

    var
      i, j, k: integer;
    begin
      i := AssignInteger(j, AssignInteger(k, 5));
    

    但这并不是你想要的,说你想写尽可能短的代码。

    我还是指出这一点以防万一。

    【讨论】:

      【解决方案4】:

      正如dummzeuch 所说,您可以编写自己的例程。但是,我更喜欢带有类似以下签名的签名:procedure AssignIntegers(AValue, ATargetArray);。理想情况下调用例程:AssignInteger(99, [X, Y, Z]);

      不幸的是,理想的选择不起作用,但以下过程已经足够接近并且应该足够了。它通过获取指向需要分配的整数的指针来工作。

      procedure AssignIntegers(AValue: Integer; const ATargets: array of PInteger);
      var
        I: Integer;
      begin
        for I := Low(ATargets) to High(ATargets) do
          ATargets[I]^ := AValue;
      end;
      

      以下 DUnit 测试用例演示了它的工作原理。您甚至可以将这些整数指针的数组放在手边,以便随时重新分配。

      type
        TArrayPInteger = array of PInteger;
      procedure TDelphiTests.TestAssignIntegers;
      var
        X,Y,Z: Integer;
        LGroup: TArrayPInteger;
      begin
        AssignIntegers(1, [@X, @Y, @Z]); { Pass open arrray using addresses of integers to initialise }
        CheckEquals(1, X);
        CheckEquals(1, Y);
        CheckEquals(1, Z);
      
        LGroup := TArrayPInteger.Create(@X, @Y); { Handy technique to initialise dynamic arrays }
        AssignIntegers(2, LGroup);
        CheckEquals(2, X);
        CheckEquals(2, Y);
        CheckEquals(1, Z); { Not part of group }
      end;
      

      警告

      唯一真正的缺点是您丢失了类型检查。编译器不会阻止您传递非整数类型的地址。这可能会导致破坏其他结构的数据或访问违规。

      【讨论】:

        猜你喜欢
        • 2014-01-20
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        • 2022-11-21
        • 1970-01-01
        • 2019-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多