Delphi 语言发展建议






4.83/5 (19投票s)
我希望在 Delphi 中看到的功能还有很多,但在这里我将介绍那些易于实现,但能带来巨大收益的功能。
自从 ~Delphi 2010 以来,我们已经有了泛型、属性、迭代器以及其他一些编译器特性。虽然许多我们想要的功能难以实现,但我相信一些简单的语言特性已经迫在眉睫。
我希望在 Delphi 中看到的功能还有很多,但在这里我将介绍那些易于实现,但能带来巨大收益的功能。
块级变量声明
大多数编译器只是在内部将块级变量声明为普通的局部变量,即这只是语法上的(但非常有用!)糖衣。甚至可以通过预处理器来实现,但这会很笨拙并影响调试器。
最简单的方法是扫描块变量。在内部将它们视为局部变量。但添加一个前缀或后缀,使用否则无法使用的字符,并为每个块分配一个 ID。
例如,为每个块分配一个数字,1、2、3、4... 然后对于每个块变量,在内部将其命名为 name$1
或类似名称。实现起来非常简单,对编译器的影响也很小。
procedure Test();
begin
for var c:string in List do begin
...
end;
var d:TStrings = TStringList.Create;
var x:integer = 7;
for var f:integer := 1 to 10 do begin
// Usable in block only. Not same as x declared before.
// Internally is just a normal function level var, ie as x$2 or something.
var x:integer = 5;
...
end;
end;
类型推断
function Foo(): integer; var x = 1; xList = TStringList.Create; begin ... for var x in xList do begin ... end; end;
using语句
带有隐式 finally 释放块的 try 语句
让我向您展示这将如何改变现有代码
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream;
xWriter: TWriter;
begin
xWriter := TWriter.Create(aSrc); try
xStream := TStringStream.Create; try
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
finally xStream.Free; end;
finally xWriter.Free; end;
end;
使用
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream;
xWriter: TWriter;
begin
using var xWriter := TWriter.Create(aSrc) do begin
using var xStream := TStringStream.Create do begin
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
end;
end;
end;
自动释放
当然,这适用于 Windows 编译器,不适用于基于 ARC 的编译器。总有一天,ARC 编译器也会达到 Windows 的水平,但在那之前,这个解决方案简单而有用。
还有其他可能的替代语法,但主要目标是功能。关键字的确切名称也不太重要。Auto 比 autofree、dynamic、finalized 等更短,更容易输入。
procedure Test2();
var
x: integer;
y: TStrings = TStringList.Create; auto;
begin
...
auto z = TStringList.Create;
...
// At proc end, all .Free is called for all auto declared variables.
// ie in this case, compiler emits a hidden y.Free and z.Free
end;
让我向您展示这将如何改变现有代码
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream;
xWriter: TWriter;
begin
xWriter := TWriter.Create(aSrc); try
xStream := TStringStream.Create; try
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
finally xStream.Free; end;
finally xWriter.Free; end;
end;
使用 auto
class function TMyWriter.ToString(aSrc: TRoot): string;
var
xStream: TStringStream; auto;
xWriter: TWriter; auto;
begin
xWriter := TWriter.Create(aSrc);
xStream := TStringStream.Create;
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
end;
或者与块声明变量结合使用
class function TMyWriter.ToString(aSrc: TRoot): string;
begin
auto xWriter := TWriter.Create(aSrc);
auto xStream := TStringStream.Create;
xWriter.SaveToStream(xStream);
Result := xStream.DataString;
end;
三元运算符
很难相信 Delphi 已经超过 20 年了,我们仍然没有三元运算符。语法可以有所不同,但其他语言中长期使用的语法可以很容易地适应 Delphi。
xValue := xCondition ? 'one' : 'two';
一位评论者还建议参考 Scala 的语法,我非常喜欢这种更像 Delphi 的语法
xValue := if xCondition then 'one' else 'two';
结论
通过这些简单的添加,Delphi 将更容易编写代码,而不会损失任何功能。