DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> AJAX入門 >> AJAX詳解 >> D語言中的混入(Mixin)
D語言中的混入(Mixin)
編輯:AJAX詳解     

混入

混入(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
	}
	
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved