我可以在函数内部声明变量吗,而不是在函数的顶部声明?

3

我大约5年前使用过Visual Basic。

但是5年前我开始使用Delphi(当时大多数开发人员从Delphi转向Visual Studio)。 Delphi和VB一样易于操作,同时具有RAD和健壮性。 Delphi自Pascal以来发生了许多变化(例如:在Pascal中必须以不同的方式组合字符串,而不能仅使用“+”),以加快脚本速度。

但是为什么在Delphi中我们必须在顶部声明变量,当我正在为一个过程编写许多语句时,我必须向上滚动并声明一个变量,再返回下来。 Delphi是世界上最快速的IDE之一(有时甚至是唯一的),但为什么他们没有像VB、C#等语言那样支持在任何地方声明变量呢?


3
Pascal是按照这种方式设计的,甚至比Delphi更加严格(即Pascal强制执行类型/常量/变量序列,如果我没记错,它不允许像Delphi那样混合使用)。你可能喜欢或不喜欢,但它被设计成具有清晰的声明并将其与代码分离。 - user160694
1
现在你可以:https://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html。在我看来,这看起来有点不像 Pascal,但是在你习惯了它们之后可能会很方便 :) - Gabriel
5个回答

16

在新版的Delphi中,使用代码模板可以在过程中间声明一个变量,并且这个功能也默认启用了Live templates。

我只需输入var然后按下CTRL+J并输入名称和类型,IDE就会完成剩下的工作。

对我来说没什么大不了的。

Mike Rozlog演示了Live templates的使用:

http://edn.embarcadero.com/article/40284


从来不知道这个! :-) 不过还是不会用它...我的大多数方法都足够短,只需向上滚动8行,在开始之前添加变量即可。 - Wim ten Brink
我也试图保持我的方法简短,但在实际实现代码之前很少知道需要哪些变量,因此IDE的代码模板函数有助于打断程序员的思路。 ;) - Jens Mühlenhoff

15

8
感谢您指出了真正的问题。您应该努力让您的函数:尽可能小,参数尽可能少,并且只做一件事情。 - Kenneth Cochran
1
-1 对于这种说法,它并不正确。在一个项目中通常有很多程序需要超过一个屏幕高度才能更好地展示。 - Andreas

11

比 Jens 的 Ctrl-J 快捷键更好的是这个方法。

  1. 编写您的代码,例如:

I := 0;
注意到"I"下面有一个红色的波浪线(表示它未声明)。
  • 点击"I"并输入快捷键:Shift+Ctrl+V

  • 会弹出一个声明变量的窗口,通常会自动识别正确的类型。

  • 如果必要,更改类型并按回车键关闭窗口。

  • 我喜欢这个快捷方式并经常使用它。


    你可以从Shift+Ctrl+V开始,也可以按照更传统的顺序完成操作。谢谢! - Jim Mack
    Shift+Ctrl+V非常有用,但对我来说从未起作用(或随机起作用)。Delphi IDE总是非常有bug。 - Gabriel

    10
    你提出了这个问题:“为什么他们不像vb c#等一样支持在任何地方声明变量?”
    答案是:因为语言设计者认为内联声明变量会让人感到困惑和难以阅读。如果所有变量都在方法级别上声明,它们的声明很容易找到,它们的类型也很容易确定。他们认为内联声明使跟踪变量及其类型变得困难。
    其他语言设计者喜欢能够内联声明变量,但代码和变量声明之间的清晰分界是许多人喜欢Pascal的原因之一。

    5
    我认为这可以作为支持在方法顶部声明变量的一个不错的论点,但我不认为这是Delphi继承Pascal方式声明变量的真正原因。据我所知,这与语言设计决策有关,允许采用一种简单的方式来实现快速的逐步自上而下编译器。 - Trinidad
    1
    @Trinidad -- 你说得对,编译器速度在这里也是一个因素。 - Nick Hodges
    2
    @Nick - 有些语言根本不需要声明。变量是动态确定的。但是声明它们更好,因为编译器可以更好地优化它们。 - lkessler
    3
    我不认同Delphi的做法更易于阅读的观点,特别是对于那些有着深厚面向对象编程背景的人来说。比可读性更重要的是变量的隔离,这对于面向对象设计至关重要。如果我想在for循环中显式地使用x,那么x应该完全无法被循环外的任何东西访问。请记住局部作用域比全局作用域的重要性。我更倾向于Trinidad的回答。 - arkon
    1
    @b1naryatr0phy -- 没问题。就像我告诉我的孩子们一样--每个人都是不同的。我更喜欢Pascal的方式,觉得代码更容易阅读。你的情况可能会有所不同。 - Nick Hodges

    4

    从 Delphi 10.3 Rio 版本开始,可以使用 inline 声明变量和常量。

    甚至可以推断类型。

    示例:

    procedure Test1;
    begin
      var i : Integer;
      i := 10;
      WriteLn(i);
    end;
    

    变量可以内联和赋值:

    procedure Test2;
    begin
      var i : Integer := 10;
      WriteLn(i);
    end;
    

    内联变量类型可以被推断:

    procedure Test3;
    begin
      var i := 10;
      WriteLn(i);
    end;
    

    内联变量的作用域可以限定在开始/结束块中:

    procedure Test4;
    begin
      var i : Integer := 10;
      WriteLn(i);
      if i < 20 then begin
         var j := 30;
      end;
      Write(j); // <- Compiler error “Undeclared identifier: ‘j’”
    end;
    

    内联变量可以在 for-infor-to 循环中使用:

    procedure Test5;
    begin
      for var i := 1 to 10 do
        WriteLn(i);
    end;
    

    常量也可以像普通的常量一样被内联,且类型可以被推断:

    procedure Test6;
    begin
      const i : Integer = 10;
      const j = 20;
      WriteLn(j);
    end;
    

    2
    一个问题是如何可能在2010年提出,但在2018年11月27日得到回答,而且回答中提到的Delphi版本在2010年并不存在,却立即被标记为已接受的答案? - dummzeuch
    1
    @dummzeuch,我不知道你所说的“立即”是什么意思。它大约花了18个小时,但你想表达什么? - LU RD
    我的观点是,针对 Delphi 2009 是当前版本的2010年问题,不能通过引用于在2018年发布的 Delphi 10.3 来回答,并且该答案被接受为正确。它应该至少提到内联变量声明在任何旧版本中都不可用。 - dummzeuch
    3
    如果有人搜索如何在Delphi中内联声明变量的可能性,那么如果这个答案被从这个问题的Q/A站点中排除掉,就会显得很奇怪。 - LU RD

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接