D语言中的声明

博客主要介绍了D语言的声明相关内容。包括声明语法,通常从右向左读,也有数组不同的声明方式;别名声明,可将符号声明为另一符号的别名,用于简化符号、重定位引用等;还介绍了typeof,用于获得表达式类型,在编写模板代码时很有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

声明

	声明:
		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

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 大有用武之地。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值