zoukankan      html  css  js  c++  java
  • Delphi 7以来的Delphi 2009测试版新语法特性

    我晕,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
  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/findumars/p/3659144.html
Copyright © 2011-2022 走看看