• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
                為了讓更高級(jí)的語(yǔ)言可以編譯到Vczh Library++ 3.0上面的NativeX語(yǔ)言,原生的泛型支持是必須有的。泛型不僅僅是一堆代碼的填空題那么簡(jiǎn)單,因?yàn)榫幾g之后的Assembly(dll)必須可以容納泛型聲明,而且其他的Assembly可以實(shí)例化包含在其他Assembly里面的泛型聲明。這是非常麻煩的(被.net搞定了,jvm則由于種種原因搞不定,大概是因?yàn)閖vm對(duì)assembly version的支持太差導(dǎo)致的,你知道.net 2.0的東西是不能引用4.0的dll的……)。不過(guò)先拋開(kāi)這個(gè)不講,雖然如何在Assembly里面實(shí)現(xiàn)泛型我已經(jīng)心里有數(shù)了,但是這里還是從語(yǔ)義的層面上來(lái)考慮泛型的設(shè)計(jì)。

                在討論之前還是要強(qiáng)調(diào)一下一個(gè)大前提:NativeX基本上就是一個(gè)語(yǔ)法更加容易看懂的C語(yǔ)言而已,功能完全是等價(jià)的。于是我要在NativeX上加泛型,其實(shí)也就是等于在C上面加泛型。我們使用泛型完成的事情可以有很多,譬如說(shuō)定義泛型的結(jié)構(gòu)體,定義泛型的函數(shù),還有泛型的存儲(chǔ)空間等等。首先讓我們討論泛型的結(jié)構(gòu)體。最終的語(yǔ)法可能會(huì)跟現(xiàn)在不一樣,因?yàn)镹ativeX的使命是作為一棵語(yǔ)法樹(shù)出現(xiàn)的,所以做得太漂亮的價(jià)值其實(shí)不是很大。

                一、泛型結(jié)構(gòu)體

                泛型的結(jié)構(gòu)體還是比較容易理解的,舉個(gè)小例子:
            1 generic<type T>
            2 structure Vector
            3 {
            4   T x;
            5   T y;
            6 }

                這樣子我們就創(chuàng)建了一個(gè)泛型的結(jié)構(gòu)體。任何熟悉C++或C#的人都知道這是什么意思,我就不做解釋了。使用的時(shí)候跟我們的習(xí)慣是一樣的:
            1 Vector<double> v;
            2 v.x = 1.0;
            3 v.y = 2.0;

                于是我們創(chuàng)建了一個(gè)泛型的變量,然后修改了它的成員。

                二、泛型全局存儲(chǔ)空間

                其實(shí)泛型的全局存儲(chǔ)空間基本上等于編譯器替你做好的一個(gè)key為類型的大字典。有些時(shí)候我們需要給類型加上一些附加的數(shù)據(jù),而且是按需增長(zhǎng)的。這就代表在編譯的時(shí)候提供泛型全局存儲(chǔ)空間的Assembly并不知道將來(lái)有多少個(gè)key要提供支持,所以創(chuàng)建它們的工作應(yīng)該是虛擬機(jī)在鏈接一個(gè)想使用其他Assembly提供的全局空間的新Assembly的時(shí)候創(chuàng)建的。這里帶來(lái)了一個(gè)問(wèn)題是不同的Assembly使用相同的類型可以訪問(wèn)相同的全局存儲(chǔ)空間,這里先不討論具體實(shí)施的手段。

                語(yǔ)法上可能比較混淆:
            1 generic<type T>
            2 structure TypeStorage
            3 {
            4   wchar* name;
            5   function T() builderFunction;//這是函數(shù)指針
            6 }
            7 
            8 generic<type T>
            9 TypeStorage<T> typeStorage;

                在一個(gè)變量上面加泛型可能會(huì)有點(diǎn)奇怪,不過(guò)這里的定義還是很明確的。typeStorage是全局變量的泛型,因此typeStorage<int>、typeStorage<double>甚至typeStorage<Vector<Vector<wchar*>>>等等(啊,>>問(wèn)題)是代表不同的全局變量。不同的Assembly訪問(wèn)的typeStorage<int>都是相同的全局變量。

                三、泛型函數(shù)

                泛型函數(shù)我們也都很熟悉了。一個(gè)簡(jiǎn)單的例子可以是:
            1 generic<type T>
            2 T Copy(T* pt)
            3 {
            4   result = *pt;
            5 }

                需要指出的是,NativeX并沒(méi)有打算要支持泛型結(jié)構(gòu)、全局存儲(chǔ)和函數(shù)的特化或偏特化。因此我們會(huì)很驚訝的發(fā)現(xiàn)這樣的話泛型函數(shù)唯一能做的就是復(fù)制東西了,因?yàn)樗{(diào)用不了其他的非泛型函數(shù)(跟C++不一樣,NativeX的泛型函數(shù)更接近于C#:編譯的時(shí)候進(jìn)行完全的語(yǔ)義分析)。雖然泛型函數(shù)可以調(diào)用其他的泛型函數(shù),但是最終也只能做復(fù)制。因此我們要引入一個(gè)新的(其實(shí)是舊的)概念,才可以避免我們?yōu)榱颂峁└鞣N操作在泛型函數(shù)的參數(shù)上傳入一大堆的函數(shù)指針:“概念”。

                四、泛型concept

                泛型結(jié)構(gòu)體和全局存儲(chǔ)僅僅用來(lái)保存數(shù)據(jù),所以泛型concept只能在泛型函數(shù)上面使用。這個(gè)concept跟C++原本打算支持的concept還是很接近的,只是NativeX沒(méi)有class,因此只好做一點(diǎn)小修改。

                泛型concept主要是為了指定一套操作的接口,然后讓編譯器可以完成比調(diào)用函數(shù)指針更加高效的代碼。偷偷告訴大家,把他叫concept只是因?yàn)镹ativeX跟C很像,但其實(shí)這個(gè)概念是從Haskell來(lái)的……我們還是來(lái)看看concept怎么寫(xiě)吧。
             1 generic<type T>
             2 concept Addable
             3 {
             4   operation T add(T a, T b);
             5   operation T sub(T a, T b);
             6   constant T zero;
             7 }
             8 
             9 generic<type T>
            10 concept Multible : Addable<T>
            11 {
            12   operation T mul(T a, T b);
            13   operation T div(T a, T b);
            14   constant T one;
            15 }

                這里定義了加法和乘法的兩個(gè)concept。我們可以看出concept是可以繼承的,其實(shí)也是可以多重繼承的。concept里面可以放操作(operation),也可以放常數(shù)(constant)。這里的常數(shù)跟全局存儲(chǔ)的機(jī)制不同,全局存儲(chǔ)可以自動(dòng)為新類型產(chǎn)生可讀寫(xiě)的空間,而concept的常數(shù)不僅是只讀的,而且還不可自動(dòng)產(chǎn)生空間。之前考慮到的一個(gè)問(wèn)題就是,我們可能需要把外界提供的某個(gè)concept的operation的函數(shù)指針提取出來(lái),有這種需要的operation可以把這個(gè)關(guān)鍵字替換成function,這樣在實(shí)例化concept的時(shí)候,那個(gè)標(biāo)記了function的操作就只能綁定一個(gè)函數(shù)而不是一個(gè)表達(dá)式了。我們可以嘗試為int創(chuàng)建一個(gè)Multible的concept:
            1 concept instance IntMultible : Multible<int>
            2 {
            3   operation T add(T a, T b) = a+b;
            4   operation T sub(T a, T b) = a-b;
            5   operation T mul(T a, T b) = a*b;
            6   operation T div(T a, T b) = a/b;
            7   constant T zero = 0;
            8   constant T one = 1;
            9 }

                于是我們可以寫(xiě)一個(gè)函數(shù)計(jì)算a+b*c:
            1 generic<type T, concept Multible<T> multible>
            2 function T AddMul(T a, T b, T c)
            3 {
            4   return multible.add(a, multible.mul(b, c));
            5 }

                然后調(diào)用它:
            1 int r = AddMul<int, IntMultible>(345);

                五、另一種concept instance

                雖然我們不允許泛型的結(jié)構(gòu)體、全局存儲(chǔ)和函數(shù)進(jìn)行特化,但是因?yàn)樘鼗瘜?shí)在是一個(gè)好東西。上面的concept instance是沒(méi)有彈性的,因?yàn)槟悴豢赡芡ㄟ^(guò)一個(gè)concept instance拿到另外一個(gè)concept instance。考慮一下delphi的帶引用計(jì)數(shù)的嵌套數(shù)組,如果我們想讓delphi可以編譯到NativeX上,則勢(shì)必要支持那種東西。主要的困難在于delphi支持的帶有引用計(jì)數(shù)的數(shù)組和字符串,因此在對(duì)array of array of string進(jìn)行釋放的時(shí)候,我們首先要拿到array of array of string的concept instance,其次在釋放函數(shù)里面要拿到array of string的concept instance,最后還要拿到string的concept instance。這個(gè)用上面所提出來(lái)的方法是做不了的。因此我們引進(jìn)了一種新的concept instance:叫concept series。這個(gè)跟haskell的東西又更接近了一步了,因?yàn)閔askell的concept instance其實(shí)是匿名但是可特化的……

                于是現(xiàn)在讓我們來(lái)實(shí)現(xiàn)Array和String,并寫(xiě)幾個(gè)類型的Increase和Decrease的函數(shù)(函數(shù)體一部分會(huì)被忽略因?yàn)檫@里只是為了展示concept):
             1 structure String
             2 {
             3   int reference;
             4   wchar* content;
             5 }
             6 
             7 generic<type T>
             8 structure Array
             9 {
            10   int reference;
            11   int length;
            12   T* items;
            13 }

                我們從這里可以看出,string跟array的區(qū)別就是在于長(zhǎng)度上面,string有0結(jié)尾而array只能通過(guò)記錄一個(gè)長(zhǎng)度來(lái)實(shí)現(xiàn)。現(xiàn)在我們來(lái)寫(xiě)一個(gè)用于構(gòu)造缺省數(shù)值、增加引用計(jì)數(shù)和減少引用計(jì)數(shù)的concept series:
             1 generic<type T>
             2 concept Referable
             3 {
             4   operation T GetDefault();
             5   operation void Increase(T* t);
             6   operation void Decrease(T* t);
             7 }
             8 
             9 generic<type T>
            10 concept series DelphiTypeReferable : Referable<T>
            11 {
            12 }

                concept series其實(shí)就是專門用來(lái)特化的concept instance。但是為了防止不同的Assembly特化出同一個(gè)concept series所帶來(lái)的麻煩,我可能會(huì)規(guī)定允許特化concept series的地方,要么是在聲明該concept series的Assembly,要么是聲明涉及的類型的Assembly。因?yàn)槲业腁ssembly不允許循環(huán)引用,因此對(duì)于同一個(gè)concept series C<T,U>來(lái)講,就算T和U分別在不同的Assembly出現(xiàn),那么也只能有一個(gè)有權(quán)限特化出它。下面來(lái)看特化具體要怎么做。首先我們特化一個(gè)簡(jiǎn)單的,string的DelphiTypeReferable:
            1 concept series DelphiTypeReferable<String>
            2 {
            3   operation GetDefault = StringGetDefault;
            4   operation Increase = StringIncrease;
            5   operation Decrease = StringDecrease;
            6 }

                StringGetDefault、StringIncrease和StringDecrease都是一些普通的函數(shù),內(nèi)容很簡(jiǎn)單,不用寫(xiě)出來(lái)。現(xiàn)在讓我們來(lái)看看Array應(yīng)該怎么做:
            1 generic<type T>
            2 concept series DelphiTypeReferable<Array<T>>
            3 {
            4   operation Array<T> GetDefault() = ArrayGetDefault<T>;
            5   operation Increase = ArrayIncrease<T>;
            6   operation Decrease = ArrayDecrease<T>;
            7 }

                看起來(lái)好像沒(méi)什么特別,不過(guò)只要想一想ArrayDecrease的實(shí)現(xiàn)就知道了,現(xiàn)在我們需要在ArrayDecrease里面訪問(wèn)到未知類型T的DelphiTypeReferable<T>這個(gè)concept instance。因?yàn)楫?dāng)自己要被干掉的時(shí)候,得將引用到的所有對(duì)象的引用計(jì)數(shù)都減少1:
             1 generic<type T>
             2 function void ArrayDecrease(Array<T>* array)
             3 {
             4   if(array->reference<=0)exit;
             5   if(--array->reference==0)
             6   {
             7     for int i = 0
             8       when i < array->length
             9       with i--
            10       do DelphiTypeReferable<T>.Decrease(&array->items[i]);
            11     free(array->items);
            12     array->length=-1;
            13     array->items=null;
            14   }
            15 }

                這樣一大堆concept series的特化組合在一起就成為會(huì)根據(jù)類型的變化而采取不同行為的concept instance了。于是我們還剩下最后的一個(gè)問(wèn)題,那么其他類型的DelphiTypeReferable應(yīng)該怎么寫(xiě)呢?其實(shí)只需要玩一個(gè)小技巧就行了,不過(guò)在這里將會(huì)看到NativeX支持泛型的最后一個(gè)功能:
             1 generic<type T>
             2 concept series DelphiTypeReferable<T>
             3 {
             4   operation GetDefault = GenericGetDefault<T>;
             5   operation Increase = null;
             6   operation Decrease = null;
             7 }
             8 
             9 generic<type T>
            10 T GenericGetDefault()
            11 {
            12 }

                返回null的operation可以賦值成null以表示不需要執(zhí)行任何東西。如果你將一個(gè)有副作用的表達(dá)式傳進(jìn)去當(dāng)參數(shù)的話,副作用會(huì)保證被執(zhí)行。

                關(guān)于語(yǔ)義上的泛型就講到這里了。
            posted on 2010-06-12 23:58 陳梓瀚(vczh) 閱讀(2538) 評(píng)論(2)  編輯 收藏 引用 所屬分類: VL++3.0開(kāi)發(fā)紀(jì)事

            評(píng)論:
            # re: Vczh Library++ 3.0之NativeX語(yǔ)言泛型草稿 2010-06-13 00:46 | radar
            仰望!!!  回復(fù)  更多評(píng)論
              
            # re: Vczh Library++ 3.0之NativeX語(yǔ)言泛型草稿 2010-06-15 03:40 | mm
            仰望!!!  回復(fù)  更多評(píng)論
              
            国产毛片欧美毛片久久久| 人妻无码中文久久久久专区| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 久久精品中文无码资源站| 久久无码中文字幕东京热| 思思久久精品在热线热| 久久天天躁狠狠躁夜夜网站| 精品久久久久久久无码| 久久e热在这里只有国产中文精品99| 久久精品人妻一区二区三区| 国产成人无码精品久久久性色 | 久久精品国产亚洲网站| 亚洲国产精品人久久| 国产免费久久精品99re丫y| 国产午夜久久影院| 久久亚洲国产成人影院| 97久久超碰成人精品网站| 久久久久99精品成人片| 无码国内精品久久人妻| 久久精品国产精品亚洲人人| 午夜精品久久久久久久| 91精品国产色综久久| 一本久久a久久精品亚洲| 精品国产乱码久久久久久浪潮| 久久天天躁夜夜躁狠狠| 国产巨作麻豆欧美亚洲综合久久| 亚洲成色WWW久久网站| 亚洲精品WWW久久久久久| 94久久国产乱子伦精品免费| 久久婷婷激情综合色综合俺也去| 三级片免费观看久久| 国内精品伊人久久久久网站| 777米奇久久最新地址| 国内精品人妻无码久久久影院导航 | 狠狠色丁香久久婷婷综合_中| 亚洲午夜久久久精品影院| 精品久久久久久无码专区| 久久亚洲精品成人无码网站| 香蕉99久久国产综合精品宅男自 | 97精品国产97久久久久久免费| 国产精品成人99久久久久 |