中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
D语言中的混入(Mixin)
作者:未知 时间:2005-07-27 23:06 出处:CSDN 责编:chinaitpower
              摘要:D语言中的混入(Mixin)

混入

混入(Mixins) 意味着用不同的编程语言表达的不同的事物。 在D中,一个混入从一个 模版声明 的过程体内提取一个任意的声明集合,并将它们插入到当前的上下文中。 
	模板混入:
		mixin 模板标志符 ;
		mixin 模板标志符 混入标志符 ;
		mixin 模板标志符 !( 模版参数列表 ) ;
		mixin 模板标志符 !( 模版参数列表 ) 混入标志符 ;

	混入标志符:
		标志符
	TemplateMixin:
		mixin TemplateIdentifier ;
		mixin TemplateIdentifier MixinIdentifier ;
		mixin TemplateIdentifier !( TemplateArgumentList ) ;
		mixin TemplateIdentifier !( TemplateArgumentList ) MixinIdentifier ;

	MixinIdentifier:
		Identifier
	
模版混入 可以出现在模块、类、结构、联合以及语句的声明列表中。模板标志符 是一个 模版声明 。如果 模版声明 没有参数,就可以使用不带 !(模版参数列表) 的混入形式。

不像模板具现化,模板混入的过程体在混入所在的作用域内计算,而不是在定义模板声明的地方。这等价于使用剪切和粘贴将模版的过程体插入混入的位置。这对注入参数化的‘样板文件’是有用的,同时对创建模板化嵌套函数也很有用,而正常情况下是不可能具现化嵌套函数的。

	template Foo()
	{
	    int x = 5;
	}

	mixin Foo;

	struct Bar
	{
	    mixin Foo;
	}

	void test()
	{
	    printf("x = %d\n", x);		// 打印出 5
	    {
		Bar b;
		int x = 3;

		printf("b.x = %d\n", b.x);	// 打印出 5
		printf("x = %d\n", x);	// 打印出 3
		{
		    mixin Foo;
		    printf("x = %d\n", x);	// 打印出 5
		    x = 4;
		    printf("x = %d\n", x);	// 打印出 4
		}
		printf("x = %d\n", x);	// 打印出 3
	    }
	    printf("x = %d\n", x);		// 打印出 5
	}
	
混入可以被参数化:
	template Foo(T)
	{
	    T x = 5;
	}

	mixin Foo!(int);		// 创建类型为 int 的 x
	
混入可以可以为类添加虚函数:
	template Foo()
	{
	    void func() { printf("Foo.func()\n"); }
	}

	class Bar
	{
	    mixin Foo;
	}

	class Code : Bar
	{
	    void func() { printf("Code.func()\n"); }
	}

	void test()
	{
	    Bar b = new Bar();
	    b.func();		// 调用 Foo.func()

	    b = new Code();
	    b.func();		// 调用 Code.func()
	}
	
混入在它们出现的地方被求值,而不是在模板声明的地方:
	int y = 3;

	template Foo()
	{
	    int abc() { return y; }
	}

	void test()
	{
	    int y = 8;
	    mixin Foo;	// 使用的是局部的 y ,而不是全局的 y
	    assert(abc() == 8);
	}
	
混入可以使用别名参数来参数化符号:
	template Foo(alias b)
	{
	    int abc() { return b; }
	}

	void test()
	{
	    int y = 8;
	    mixin Foo!(y);
	    assert(abc() == 8);
	}
	
这个例子使用了一个混入来为任意语句实现一个泛型 Duff's Device(在这里,那个语句采用粗体表示)。在生成一个嵌套函数的同时也生成了一个委托文字量,他们会通过编译器内联:
	template duffs_device(alias id1, alias id2, alias s)
	{
	    void duff_loop()
	    {
		if (id1 < id2)
		{
		    typeof(id1) n = (id2 - id1 + 7) / 8;
		    switch ((id2 - id1) % 8)
		    {
		        case 0:        do {  s();
		        case 7:              s();
		        case 6:              s();
		        case 5:              s();
		        case 4:              s();
		        case 3:              s();
		        case 2:              s();
		        case 1:              s();
					  } while (--n > 0);
		    }
		}
	    }
	}

	void foo() { printf("foo\n"); }

	void test()
	{
	    int i = 1;
	    int j = 11;

	    mixin duffs_device!(i, j, delegate { foo(); } );
	    duff_loop();		// 执行 foo() 10 次
	}
	

混入作用域

混入中的声明被‘导入’到周围的作用域中。如果混入和其周围的作用域中有相同的名字,周围的作用域中的声明将覆盖混入中的那个声明:
	int x = 3;

	template Foo()
	{
	    int x = 5;
	    int y = 5;
	}

	mixin Foo;
	int y = 3;

	void test()
	{
	    printf("x = %d\n", x);	// 打印出 3
	    printf("y = %d\n", y);	// 打印出 3
	}
	
如果两个不同的混入被放入同一个作用域,并且他们中定义了同名的声明,就会出现模棱两可的错误:

   template Foo()
   {
       int x = 5;
   }

   template Bar()
   {
       int x = 4;
   }

   mixin Foo;
   mixin Bar;

   void test()
   {
       printf("x = %d\n", x); // 错误,x 模棱两可
   }

如果一个混入中有 混入标志符 ,它可以用来消除歧义:
	int x = 6;

	template Foo()
	{
	    int x = 5;
	    int y = 7;
	}

	template Bar()
	{
	    int x = 4;
	}

	mixin Foo F;
	mixin Bar B;

	void test()
	{
	    printf("y = %d\n", y);		// 打印出 7
	    printf("x = %d\n", x);		// 打印出 6
	    printf("F.x = %d\n", F.x);	// 打印出 5
	    printf("B.x = %d\n", B.x);	// 打印出 4
	}
	
混入有其自身的作用域,尽管声明会被外围的声明覆盖:
	int x = 4;

	template Foo()
	{
	    int x = 5;
	    int bar() { return x; }
	}

	mixin Foo;

	void test()
	{
	    printf("x = %d\n", x);		// 打印出 4
	    printf("bar() = %d\n", bar());	// 打印出 5
	}
	

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有