我晕,Delphi 7 以后增加了这么多有用的语法,我都不知道。真是越学越觉得自己浅薄,自己所作的Delphi项目所用的知识还不够Delphi知识储备体系的十分之一,更别说Delphi还在继续发展。

-----------------------------------------------------------------------

自Delphi 7以来的Delphi 2009测试版新语法特性
                 by eGust
===========================================
  
New Delphi language features since Delphi 7
-------------------------------------------
这部分对从Delphi 7到Delphi 2007的新语法特性语法进行一个简介,主要内容来自于CodeGear官方网站D2007的 "What's New" 中对新语法特性的介绍的部分:
http://edn.embarcadero.com/cn/article/34324
  
1.内联函数(Inlining)(似乎不需要,有几个项目还差那一点点执行时间呢,都是时间更重要,项目做的做不出来更重要)
D7中的inline关键字作为保留字并不会对编译器产生实际作用,在2009中此关键字起到内嵌到代码中起到实际作用。语法如下:
   function foo: Integer; inline;
内部函数/过程也可以使用,但在D2009测试版中,类方法的内部函数使用inline后不认Self指针;类的子过程/子函数,也可以使用inline关键字,但没有实际效果,且虚方法/继承方法(virtual/override)不能使用。
  
  
2.重载运算符(Operator Overloading)(最讨厌运算符重载,语法上看上去简单好用,其实除了数学领域哪里都用不上,函数解决一切!)
可以重载部分运算符,如 、-、类型转换等,在D2006只支持到record,但从2007开始支持到Class,以下示例修改自官网:
  
     TMyClass = class  
       // Addition of two operands of type TMyClass  
       class operator Add(a, b: TMyClass): TMyClass;  
       // Subtraction of type TMyClass  
       class operator Subtract(a, b: TMyClass): TMyclass;  
       // Implicit conversion of an Integer to type TMyClass  
       class operator Implicit(a: Integer): TMyClass;  
       // Implicit conversion of TMyClass to Integer  
       class operator Implicit(a: TMyClass): Integer;  
       // Explicit conversion of a Double to TMyClass  
       class operator Explicit(a: Double): TMyClass;    
     end;  
  
   class operator TMyClass.Add(a, b: TMyClass): TMyClass;  
   begin  
     //...  
   end;  
  
   var  
     x, y: TMyClass  
   begin  
     x := 12; // Implicit conversion from an Integer  
     y := x x; // Calls TMyClass.Add(a, b: TMyClass): TMyClass  
   end;
 
3.类助手(Class Helpers)(看上去很牛,但要想想哪里需要这个功能,会用以后也许很强大,因为可以轻易给TObject和TComponent加功能,然后所有的Delphi类都能使用!开发人员可以对做VCL全局的修改,扩展成自己的类库,但不必修改VCL源码本身!!)
Helper是对原Class的扩展,是我们在不修改原类的基础上增加类方法,并加入原类的空间中。在Delphi中,对对象的调用实际上采用了两个步骤,首先是把对象地址放入eax寄存器中,然后call类方法,所以如果不使用继承类增加数据的话,用父类调用继承类的方法是没问题的,所以其实这样的方法在D7中也可以使用,但却很麻烦。所以Class Helper起到的就是这个作用,在Class Helper中可以增加的就是与实例无关的内容,所以任何需要增加实例Size的活VMT的功能不能声明,例如变量、虚方法等,但只占用类空间的没关系, 如class var。在应用上我们可以通过这种方法方便的给VCL一类控件加上某个属性。
   TFoo = class helper for TControl  
     private  
       function GetA: Integer;  
     public  
       class var X: Integer;  
       procedure MSG(var Message: TMessage); message WM_MYMESSAGE;  
       procedure FooProc;
       property A: Integer read GetA;  
     end;  
   // ...  
   procedure TForm1.Foofoo;  
   begin  
     FooProc; // TControl -> TWinControl -> TScrollingWinControl-> TCustomForm -> TForm -> TFrom1: Call TFoo.FooProc
   end;  
  
4.strict关键字(Keyword “strict”)(一般般,控制那么严格真的有用吗?没这些语法,Delphi也已经很强大了,为所欲为。我们要的是产品和结果,还有时间,不是中间的理论或者代码如何考究,那个没用)

众所周知,在Delphi中,类的private和protected域中的变量可以被同一单元中可以自由的被访问(Delphi的类没有“友元”的概 念,但同一个unit中可以说自动友元化了),而并非是真正的私有或只能被继承类访问。而strict关键字的作用就是使该内容变成严格OO意义上的 private/protected作用域,这点没有什么多说的。语法:
   strict private
     // Blah...
   strict protected
     // Blah...
  
5.结构方法(Records with Methods)(有点意思,C++里早就是与生俱来的)
也没什么特别的,就是和class差不多,就一个不用创建和销毁、不能继承、没有作用域之类的类,很容易掌握,所以这里就不多介绍了。但是很有意思的是带参数的constructor可以通过编译,可能是为了初始化的方便吧。
  
  
6.抽象类和固实类(Abstract and Sealed Classes)(概念上有用,实际上没用,好像是这样。除非在多个开发者之间传递设计,但是设计也是要经常修改的啊,不要说某个函数、某个类,就是整个设计都有可能被推翻的啊,语言都有可能被换掉,这些个语法糖顶什么用呢)
这两个概念在OO中也并不陌生,抽象类是不应该创建实例的(但D2006起的编译器就不给检查,连个Warning都没有,这还有啥用啊 -.- ),而固实类是不能被继承的。
语法:
   TAnAbstractClass = class abstract  // or (TParentClass)
     // Blah...
   end;
   TASealedClass = class sealed(TAnAbstractClass) // or empty
     // Blah...
   end;
  
  
7.类常量、类变量、类属性与静态类方法(Class const/var/property and Static Class Methods)(这个很牛,我喜欢。以前的Delphi书上总说这个不足那个不足,现在都有了)
老的Delphi中只提供了类方法,而没有提供类变量、类常量和类属性,这真的是很不方便。这里先区分一下我所使用的类(Class)和对象 (Object)即类的实例(Instance of Class)。当在Delphi中声明一个类的时候,这个类是有实际地址的,该地址记录了许多类的相关信息,比如实例的Size啊、虚方法信息啊一堆东 西,而创建一个对象的时候则把类实例化,在堆(Heap)中分配一块地址,包括内部数据和VMT之类的东西。在调用实例的时候,首先要知道对象地址,然后 才能访问内部变量和调用方法时使用Self指针即实例地址;而在调用类方法的时候,eax中的并不是实例的地址而是类的地址,然后再call方法,这时的 Self指针并非实例地址而是类地址。所以对于每一个类和继承类来说,包括它和它的继承类的所有实例,类变量、常量都是同一个,这样就存在了一个唯一的可 供使用的变量或常量,方便同步并且不需要使用较多的内存(可以参考C#中的类,不过C#中不允许从实例直接访问类变量、常量、方法)。而静态类方法则是在 使用这个类方法的时候不传入class地址,也就是说没有Self指针,这样的类方法的访问开销要小于普通的类方法;这自然也就意味着,该类方法不能被继 承(不能virtual/override)。另外,类属性的get/set方法必须使用静态类方法。
   TFooClass = class  
   private  
     class procedure SetFoo(const Value: Integer); static; // A Static Class Method
   protected  
     class var FX : Integer; // class var
   public  
     const FC: Integer = 10; // class const
     class procedure VirtualProc; virtual;  
     class property X: Integer read FX write FX; // class property
     class property Foo: Integer read FC write SetFoo;  
   end;
  
  
8.类内部类型与嵌套类(Class Types and Nested Classes)(不喜欢,原因同内部类)
可以说现在的Class的域几乎相当于原来的整个unit,以前不能放里面的元素现在都可以放里面了,这个也没什么好多说的,试验一下就很容易明白了。
 
9.终方法(Final Methods)(没想到啊没想到,Delphi也有了这玩意,虽然概念很好,不过实际开发从未用到过,也许只有大型项目才有可能用到?)
这个也是建立在虚方法的基础上的,在override后使用final关键字,则表示该虚方法不能再被子类继承下去了。
   TAClass  = class
   public  
     procedure Foo; virtual;
   end;  
   TFinalMethodClass  = class(TAClass)  
   public  
     procedure Test; override; final; // A Final Method
   end;
  
10. For-in循环(For-in Loop)(这个我喜欢,更自然,不要样样东西都用下标找)
这个应该是受.Net影响吧,支持遍历一个数组或提供了GetEnumerator函数的类。GetEnumerator要求返回一个类的实例,该类包含有Current属性和MoveNext方法。
procedure Foo(List: TStrings);
   i : Integer;  
   lst : array[0..100]of Integer;  
   s : string;
begin  
   for i in lst do ;
   for s in List do ; // Support of TStrings.GetEnumerator
end;
  
  
=========================================================
  
         Delphi 2009测试版的新语法特性
-------------------------------------------
结束了对到Delphi 2007的语法回顾,终于正式进入到最激动人心的2009新语法部分了。
  
1.String的变化与增强了的Exit(这个还可以,可用可不用)
为全面支持Unicode,Delphi 2009中的所有跟String相关的部分都由原来的AnsiString变成了UnicodeString。这自然也就意味着,原来一些用String 声明的函数现在可能会有一些问题(好在我都不厌其烦的用AnsiString和WideString)。这同时意味着Char已经是WideChar而不 再是AnsiChar、PChar也是PWideChar而不再是PAnsiChar了。在使用D2009编程时一定要时刻小心和注意这个地方。
  
而Exit则变成了类似C的return的作用,不过退出参数是可选的,这样才能兼容以前的代码和Result关键字。虽然说这是一个小改进,但是减少了每次不厌其烦的
   if(not True)then  
   begin  
     Result  := nil;  
     Exit;  
   end;
而只需
   if(not True)then Exit(nil);
即可了。
 
2.匿名方法引用(reference to)(最讨厌内部类,虽然也许总体结构更有条理、少了一些函数,但观察当前函数的逻辑变复杂了,也不利于修改和复用,反正我就是讨厌内部类)
以前我们创建一个方法引用的时候会很麻烦,尤其是在类中,需要跳出去在别的地方写一段函数,然后再回来继续写。新的语法reference to避免了这种情况的发生,尤其是许多时候其实我们的方法实际上只有一两句的时候,它可以大大加快开发的速度,就像前面的Exit语法加强一样贴心。不过 遗憾的是,这个类lamda方法的语法糖还不够甜。
type  
   TFoo = reference to function(num: Integer): Integer; // reference to Method
var  
   func: TFoo;  
   n: Integer;  
begin  
   func := function(a: Integer): Integer // *NOTE*: Do NOT Write ‘;’
   begin  
     Result := a * a;  
   end;  
   n := func(10);
  
3.增强了的反射单元ObjAuto (应该很重要,可惜自己做的项目太浅薄,用不到这方面的功能)
这个是RTTI里的,按说不算语法上的更新,但涉及到编译器,又在RTTI方面非常有用,所以这里我还是把它拿出来说了。看过李维的《Inside VCL》的应该都知道TypInfo单元在RTTI中的重要性,而ObjAuto可以说是TypInfo的增强版。
  
先来点儿预备知识:一般情况下,class声明中的默认区域是public,但TPersistent指定了{$M }编译器参数,使得包括其继承类(所 有VCL控件)的默认区域都成为了published。以前我们可以通过TypInfo获取published区域的方法信息,成为了许多控件自动化功能 的重要组成部分。而在2009中又增加了{$METHODINFO ON}/ {$METHODINFO OFF}编译器选项,使ObjAuto单元能够获取public区域中的方法信息。具体的示例请看这个链接:http://www.cnblogs.com/del/archive/2008/08/16/1269359.html
  
  
4.泛型(重要,赶紧呀,找机会尽量把这个功能用到自己项目里去)
终于到了最激动人心、让人欢喜让人忧的泛型了。大家都知道C 难,异常难,用了十几二十年的人严谨点儿的话也不敢说自己非常懂C 。除了各种 cast、实例的创建外,操作符的重载、泛型的支持使得C 变成一个自由度极高的语言,而复杂度也因此上了一个量级。有人说C 的精华就在于 Templates,也就是泛型的支持,以我对C 的浅见,窃以为此话还是有一定道理的。在Delphi引入泛型的支持后(还好Delphi的操作符是 关键字比较多,不适合重载),许多人担心的是,编译速度会不会变慢。在用了D2009beta版之后,至少目前几个测试项目还体会不到速度的明显降低,好 在Delphi里没有C/C 那么复杂的预编译宏。不过就我目前的测试来看,Delphi 2009对泛型的支持还不是那么好,比如class<T>中内嵌type定义record中如果使用了类型为T的泛型成员的话,编译是会挂掉 的。虽说有还不算太麻烦的用class代替并且不用默认方式的构架/析构过程的trick来避免这一问题(直接用class模拟record会导致如泛型 包含string之类时会发生leak),但不够强大的泛型支持还是比较麻烦的事。
  
泛型的语法并不复杂,类似C ,在元素名称后使用“<>”包围泛型列表,如“Arr<T>=Array of T”“<TA, TB>”等,在其对应的作用域中可见。可以使用泛型的只有两种情况,一种是新定义一种类型的时候,这个类型可以是record、class、 interface、array等,另外一种情况是一个class的方法、类方法可以单独定义泛型,但普通函数/过程不能定义泛型。这里就不具体举例了, 有兴趣的可以参考Delphi 2009中自带的Generics.Collections单元中的几个基本类型。
 
5.其他(String极其好用,但往深了研究就发现里面有无穷的讲究和陷阱,不信你可以自己搜,有许多问题是你做梦都想不到的)
由于对Unicode支持是一个局大变化,所以由此带来的Windows单元、VCL组件单元带来的变化也不小,其他相关的支持单元也加入了许多元素和 进行了一些较大的调整。比如新加入的TEncoding和对TStrings、TStream系列的增强,以及TStringBuilder这种
 
-----------------------------------------------------------------------------
我忽然明白了,加了这么多新语法,是为了严格控制项目——即大型多人项目的时候使用,会产生更少的误解。
上传书籍:
http://files.cnblogs.com/findumars/DelphiXE3Starter.pdf

Delphi 7以来的Delphi 2009测试版新语法特性的更多相关文章

  1. [C#] 回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性

    回眸 C# 的前世今生 - 见证 C# 6.0 的新语法特性 序 目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段.C# 6.0 ...

  2. 总结常见的ES6新语法特性

    前言 ES6是即将到来的新版本JavaScript语言的标准,他给我们带来了更"甜"的语法糖(一种语法,使得语言更容易理解和更具有可读性,也让我们编写代码更加简单快捷),如箭头函数 ...

  3. 总结常见的ES6新语法特性。

    前言 ES6是即将到来的新版本JavaScript语言的标准,他给我们带来了更"甜"的语法糖(一种语法,使得语言更容易理解和更具有可读性,也让我们编写代码更加简单快捷),如箭头函数 ...

  4. C#新语法特性前瞻

    今天逛微软的UserVoice site发现了几个有很有用,也很可能被添加到新版C#中的语法,当然也可能被推迟到下一版,拿出来给大家分享一下. 另外还没投票的可以去为自己最想要的新特性投票,有兴趣的可 ...

  5. C#6.0的新语法特性

    https://www.cnblogs.com/dotnet261010/p/9147707.html https://www.cnblogs.com/wangdodo/p/7929050.html

  6. c# 7.0新语法特性

    public class NewAtturibute { public void TestFunc() { // 01 Out变量 不用初始化 "; if (int.TryParse(inp ...

  7. class helper 可能是从 Delphi 2007 增加的新语法

    class helper 可能是从 Delphi 2007 增加的新语法, 因为感觉不太实用, 直到今天才测试了一下. 试过之后才知道: 挺有意思的! 基本功能就是修改已存在的类. Txxx = cl ...

  8. 我的 Delphi 学习之路 —— Delphi 的认识

    标题:我的 Delphi 学习之路 -- Delphi 的认识 作者:断桥烟雨旧人伤 1. 什么是 Delphi Delphi 是 Windows 平台下著名的快速应用程序开发工具(Rapid App ...

  9. Delphi自定义消息应用及delphi托盘实现

    Delphi自定义消息应用及delphi托盘实现interfaceuses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Co ...

随机推荐

  1. linux 下 异步IO

    方法一:使用fcntl来置O_ASYNC位. 这个方法的效果是,当输入缓存中的输入数据就绪时(输入数据可读),内核向用F_SETOWN来绑定的那个进程发送SIGIO信号.此时程序应该用getchar等 ...

  2. 快充 IC BQ25896 的 ICO (input current optimizer)

    ICO (input current optimizer) 手機接上 adapter 後, 手機裡的 charger IC bq25896 開始向 adapter 抽取 current 供給 batt ...

  3. andriod多线程

    用ThreadHandle可以实现多线程,然后再主线程更新UI 第二种就是用 AsyncTask 具体看代码 public void onClick(View v) { new DownloadIma ...

  4. 基于现有图像数据创建自定义像素格式的 BufferedImage

    在最近的一个项目中,需要实现 Mac OS X 环境下的摄像头图像实时捕获并转换为 Java 中的 BufferedImage 对象.首先通过开发一个本地库实现 Mac OS X 的摄像头图像捕获,采 ...

  5. react的key值的作用

    因为在reactelement中有一个属性是key,该属性默认是为空值,所以一般情况下,只要组件不加上key值,react是不会去校验组件的key,而是直接采用diff算法进行对比,一旦组件加上了ke ...

  6. Java heap space设置方法记录

    最近被 OutOfMemory Error折腾得够呛,记载一点设置JVM虚拟机内存Javaheap space的方法. Tomcat 7 参考:  http://www.davidghedini.co ...

  7. sqlserverinternals.com

    http://sqlblog.com/blogs/kalen_delaney/default.aspx https://sqlserverinternals.com/

  8. 天啦噜!原来Chrome自带的开发者工具还能这么用!

    作者:余博伦链接:https://zhuanlan.zhihu.com/p/22665710来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Chrome自带开发者工具. ...

  9. DevExpress右键菜单使用 z

    添加BarManager和popupMenu组建: 设置popupMenu组件的Manager属性: 右键点击popupMenu主键,点击Customize选项添加菜单:    然后便可添加到鼠标事件 ...

  10. 查看java中的线程个数名称

    查看java中的线程个数名称 package com.stono.thread2; import java.lang.management.ManagementFactory; import java ...