声明
声明: typedef Decl alias Decl Decl Decl: 存储类别 Decl 基本类型 多个声明符 ; 基本类型 声明符 函数体 多个声明符: 声明符初始值 声明符初始值 , 声明符初始值列表 声明符初始值: 声明符 声明符 = 初始值 声明符标志符列表: 声明符标志符 声明符标志符 , 声明符标志符列表 声明符标志符: 标志符 标志符 = 初始值 基本类型: bit byte ubyte short ushort int uint long ulong char wchar dchar float double real ifloat idouble ireal cfloat cdouble creal void .标志符列表 标志符列表 Typeof Typeof . 标志符列表 基本类型2: * [ ] [ 表达式 ] [ 类型 ] delegate ( 参数列表 ) function ( 参数列表 ) 声明符: 基本类型2 声明符 标志符 ( 声明符 ) 标志符 多个声明符后缀 ( 声明符 ) 多个声明符后缀 多个声明符后缀: 声明符后缀 声明符后缀 多个声明符后缀 声明符后缀: [ ] [ 表达式 ] [ 类型 ] ( 参数列表 ) 标志符列表: 标志符 标志符 . 标志符列表 模板实例 模板实例 . 标志符列表 Typeof: typeof ( 表达式 ) 存储类别: abstract auto const deprecated final override static synchronized 类型: 基本类型 基本类型 声明符2 声明符2: 基本类型2 声明符2 ( 声明符2 ) ( 声明符2 ) 声明符后缀 参数列表: 参数 参数 , 参数列表 ... 参数: 声明符 声明符 = 赋值表达式 InOut 声明符 InOut 声明符 = 赋值表达式 InOut: in out inout
Declaration: typedef Decl alias Decl Decl Decl: StorageClass Decl BasicType Declarators ; BasicType Declarator FunctionBody Declarators: DeclaratorInitializer DeclaratorInitializer , DeclaratorIdentifierList DeclaratorInitializer: Declarator Declarator = Initializer DeclaratorIdentifierList: DeclaratorIdentifier DeclaratorIdentifier , DeclaratorIdentifierList DeclaratorIdentifier: Identifier Identifier = Initializer BasicType: bit byte ubyte short ushort int uint long ulong char wchar dchar float double real ifloat idouble ireal cfloat cdouble creal void .IdentifierList IdentifierList Typeof Typeof . IdentifierList BasicType2: * [ ] [ Expression ] [ Type ] delegate ( ParameterList ) function ( ParameterList ) Declarator: BasicType2 Declarator Identifier ( Declarator ) Identifier DeclaratorSuffixes ( Declarator ) DeclaratorSuffixes DeclaratorSuffixes: DeclaratorSuffix DeclaratorSuffix DeclaratorSuffixes DeclaratorSuffix: [ ] [ Expression ] [ Type ] ( ParameterList ) IdentifierList Identifier Identifier . IdentifierList TemplateInstance TemplateInstance . IdentifierList Typeof typeof ( Expression ) StorageClass: abstract auto const deprecated final override static synchronized Type: BasicType BasicType Declarator2 Declarator2: BasicType2 Declarator2 ( Declarator2 ) ( Declarator2 ) DeclaratorSuffixes ParameterList: Parameter Paremeter , ParameterList ... Parameter: Declarator Declarator = AssignExpression InOut Declarator InOut Declarator = AssignExpression InOut: in out inout
声明语法
声明语法通常从右向左读:
int x; // x 是 int int* x; // x 是指向 int 的指针 int** x; // x 是指向(指向 int 的指针)的指针 int[] x; // x 是 int 数组 int*[] x; // x 是指向 int 的指针的数组 int[]* x; // x 是指向 int 数组的指针
数组,从左向右读(列优先):
int[3] x; // x 是有3个元素的 int 数组 int[3][5] x; // x 是有5个元素的数组,每个元素是有3个元素的 int 数组 int[3]*[5] x; // x 是有5个元素的数组,每个元素是指向有3个元素的 int 的数组的指针
指向函数的指针用关键字 function 声明:
int function(char) x; // x 是指向函数的指针,函数有一个 char 的参数,返回值类型是 int int function(char)[] x; // x 是指向函数的指针的数组,函数有一个 char 的参数,返回值类型是 int
也可以使用 C 风格的数组声明方式(行优先):
int x[3]; // x 是有3个元素的 int 数组 int x[3][5]; // x 是有3个元素的数组,每个元素是有5个元素的 int 数组 int (*x[5])[3]; // x 是有5个元素的数组,每个元素是指向有3个元素的 int 的数组的指针 int (*x)(char); // x 是指向函数的指针,函数有一个 char 的参数,返回值类型是 int int (*[] x)(char); // x 是指向函数的指针的数组,函数有一个 char 的参数,返回值类型是 int
在多重声明中,所有被声明的符号拥有相同的类型:
int x,y; // x 和 y 是 int int* x,y; // x 和 y 是指向 int 的指针 int x,*y; // 错误,多重类型 int[] x,y; // x 和 y 是 int 数组 int x[],y; // 错误,多重类型
类型定义
可以通过 typedef 引入强类型。对于函数重载和调试器来说,在语义上,强类型是类型检查系统可以将其同其他类型区分的类型。
typedef int myint; void foo(int x) { . } void foo(myint m) { . } . myint b; foo(b); // 调用 foo(myint)
Typedef 可以指定一个不同于其底层类型(underlying type)的初始值:
typedef int myint = 7; myint m; // 初始化为 7
类型别名
有时为类型起一个别名是很方便的,例如可以作为一个冗长复杂类型(比如一个函数指针)的简写形式。在 D 中,可以使用别名声明达到这个目的:
alias abc.Foo.bar myint;
别名类型在语义上等价于原类型。调试器无法区分它们,在函数重载是也不会区分它们。例如:
alias int myint; void foo(int x) { . } void foo(myint m) { . } //错误,多次定义了函数 foo
类型别名等价于 C 中的 typedef 。
别名声明
符号可以被声明为另一个符号的 别名 。例如:
import string; alias string.strlen mylen; ... int len = mylen("hello"); // 实际上调用的是 string.strlen()
下面的别名声明是合法的:
template Foo2(T) { alias T t; } alias Foo2!(int) t1; alias Foo2!(int).t t2; alias t1.t t3; alias t2 t4; t1.t v1; // v1 的类型是 int t2 v2; // v2 的类型是 int t3 v3; // v3 的类型是 int t4 v4; // v4 的类型是 int
别名符号可以将一个较长的符号简记为一个较短的符号,还可以将一个引用从一个符号重定位到另一个符号:
version (Win32) { alias win32.foo myfoo; } version (linux) { alias linux.bar myfoo; }
别名可以用来从模块中‘导入’一个符号到当前作用域:
alias string.strlen strlen;
别名还可以‘导入’一系列的重载函数,这样就可以在当前作用域中重载函数:
class A { int foo(int a) { return 1; } } class B : A { int foo( int a, uint b ) { return 2; } } class C : B { int foo( int a ) { return 3; } alias B.foo foo; } class D : C { } void test() { D b = new D(); int i; i = b.foo(1, 2u); // 调用 B.foo i = b.foo(1); // 调用 C.foo }
注意:类型别名有时会同别名声明十分相似:
alias foo.bar abc; // 类型还是符号?
typeof
void func(int i) { typeof(i) j; // j 是 int 型 typeof(3 + 6.0) x; // x 是 double 型 typeof(1)* p; // p 是指向 int 型的指针 int[typeof[p]] a; // a 的类型是 int[int*] printf("%d/n", typeof('c').size); // 打印 1 double c = cast(typeof(1.0))j; // 将 j 转换为 double 型 }
Expression 不会被计算,只会生成它的类型:
void func() { int i = 1; typeof(++i) j; // j 被声明为 int ,i 不会自增 printf("%d/n", i); // 打印出 1 }
有两种特殊情况:就算不在成员函数中,typeof(this) 也将生成 this 在非静态成员函数中的类型。类似的,typeof(super) 也将生成 super 在非静态成员函数中的类型。
class A { } class B : A { typeof(this) x; // x 被声明为 B 型 typeof(super) y; // y 被声明为 A 型 } struct C { typeof(this) z; // z 被声明为 C* 型 typeof(super) q; // 错误,C 没有父结构 } typeof(this) r; // 错误,没有包含在类或者结构中
在编写模板代码时 Typeof 大有用武之地。