原创作者: oldrev   阅读:1073次   评论:0条   更新时间:2011-05-26    

D 2.0 Const/Final/Invariant 概念简介


    D 2.0 specs 里的相关文档可读性不佳,因此我总结了一个简单的 const/final/invariant 概念简介,更详细的用法还请参考 D  2.0 specs。
    在2.0中,invariant 和 const 有作存储类、定义类型和定义成员函数三种用途,深刻地改变了D程序编写的方式,跟C++一样,使用const/final/invariant 需要更仔细地设计和编码,回报是提供了更好的类型安全性并能让编译器产生出更高效的代码。这些 constness 特性,虽然看起来语法很复杂,但也比 C++ 的前后置 const 要容易理解记忆得多了,因为它不像 C++ 中的 const  定义那样存在很大的随意性。

1. invariant

1.1    invariant 作存储类(storage class)

    存储类是一个指定数据存储地点或方式的标志,static 就是一种存储类,用来要求编译器把数据存储到程序的静态存储区中。
    invariant 存储类定义一个真正的常量,这个常量决不能更改,甚至有可能是放在只读存储器中。因此,invariant 存储类定义的常量没有地址,编译器也会禁止任何的取地址行为。
    invariant 定义的常量只能使用初始化语法赋予初始值,如果 invariant 为引用/指针类型,那么所引用的数据也同样是 invariant 的。

1.2 invariant 作类型

    你可以用 invariant(TYPE) 的方法定义一个含有 invariant 属性的新类型,括号中的 TYPE 表示整个类型中适用于 invariant 的部分,比如: invariant(int)* ptr; 这行代码申明了一个指针变量 ptr,ptr本身是变量,但它所指向的类型 (int)是不可变的,因此 *ptr = 3; 这样的代码是一个语法错误。

1.3 invariant 成员函数

    invariant 可以用于修饰类和结构的成员函数,在 invariant 成员函数中传入的 this 指针/引用及其关联的任何东西都保证为 invariant。invariant 成员函数只能访问该类或结构的invariant 成员变量或其他 invariant 成员函数。
   

2. const

2.1 const 存储类

    const 存储类类似于 invariant 存储类,不同的是 const 定义的指针/引用所指向的数据可以是变量,因此它们可能会在其他地方被修改。

2.2 const 作类型

    与 invariant 作类型类似,const(TYPE) 定义一个含有 const 属性的新类型。不同点是当 const(TYPE) 作为指针/引用类型时,其所指向的类型可以是变量,如:int a; const(int)* ptr = &a; ptr 本身是变量,ptr 也可以指向变量,但是通过 ptr 只能只读地访问 a。

2.3 const 成员函数

    const 修饰的成员函数类似C++中函数声明后置的 const,表示他们不允许更改 "this" 指针/引用指向的对象数据。请注意这里的修辞,“不允许”意味着可以像C/C++一样用转型骗过编译器,不过欺骗编译器恐怕没什么好结果。与 invariant 成员函数类似,const 成员函数可以访问 invariant 和 const 成员变量和函数。

3. final 存储类

    final 存储类定义一个数据的访问模式为只读,与 invariant 不同的是,编译器为 final 定义的对象在内存中分配了空间。换句话来说,final 对象跟真正的变量没什么区别,只是由编译器来强制实施对此对象的只读访问。final 定义的对象可以用初始化语法初始化或在构造函数中初始化(加入 final 对象是类成员的话,当然,模块的this()也支持)。
    在成员函数方面,很早以前 final 已经用来表示禁止 override 了,final 也不能作为类型使用。


    目前 D 2.0 只是 alpha 版,还有很多的 bugs,因此,如果出现了任何不符合上面理论的问题,请怪罪编译器及其作者,而不是我,谢谢合作。

oldrev
oldrev (at) gmail . com
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

  • qiezi在2007-07-24创建
  • qiezi在2011-05-26更新
Global site tag (gtag.js) - Google Analytics