<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-30  評(píng)論-123  文章-0  trackbacks-0

    在用Java編程時(shí),大部分可執(zhí)行的代碼要么被封裝在靜態(tài)類(lèi)方法(static class methods)中,要么被封裝在實(shí)例方法(nstance methods)中(代碼 也可以被封裝在構(gòu)造函數(shù),初始化函數(shù)或初始化表達(dá)式中,但這些在這兒不重要).方法把代碼封裝在一對(duì)花括號(hào)里并給代碼段分配一個(gè)方法名.所有 這些方法必須定義在某種類(lèi)型的類(lèi)里面.例如,假設(shè)你要寫(xiě)一個(gè)返回任意整數(shù)平方的方法,這個(gè)方法可以這樣寫(xiě):

    package ?example.math;

    public ? class ?MyMath?
    {
    ???
    public ? static ? long ?square( int ?numberToSquare)
    {
    ????????
    return ?numberToSquare? *
    ?numberToSquare;
    ???}

    }
    要使用square()方法,你需要像下面一樣引用類(lèi)和方法
    import?example.math.MyMath;



    int?x,?y;
    x?
    =?2;
    y?
    =?example.math.MyMath.square(x);

    //?y?=?4.

    使用Groovy你也能完成上面的工作,不過(guò)在Groovy里面你不需要聲明任何類(lèi)和方法.這一切由閉包來(lái)完成.閉包是封裝在花括號(hào)中的一條或幾條程 序語(yǔ)句.閉包和方法的最大區(qū)別在于閉包不需要類(lèi)和方法名.下面的代碼將square()方法重寫(xiě)為一個(gè)閉包.
    {numberToSquare?->
    ?????numberToSquare?
    *?numberToSquare
    }
    ;

    正如你所看到的,除了不需要聲明類(lèi)和分配給代碼方法名.然而要說(shuō)明的是,上面的例子還不能用因?yàn)闆](méi)有使用閉包的方法.沒(méi)有標(biāo)識(shí)(方法名)我 們?cè)趺凑{(diào)用這個(gè)閉包呢?方法是:把創(chuàng)建的閉包賦給一個(gè)變量,那么你就可以使用這個(gè)變量作為閉包的標(biāo)識(shí)來(lái)調(diào)用這個(gè)閉包.
    //?初始化變量
    int?x,?y;
    x?
    =?2;

    //?創(chuàng)佳閉包并把它賦給變量C
    def?c?=?{numberToSquare?->?numberToSquare?*?numberToSquare?}

    //?使用變量C作為閉包的標(biāo)識(shí),?調(diào)用閉包
    y?=?c.call(x);

    //?y?=?4

    閉包真正優(yōu)越的地方是你可以創(chuàng)建閉包并把它賦給一個(gè)變量,并且可以像其他變量一樣在整個(gè)程序中傳遞.剛開(kāi)始,你可能覺(jué)得這沒(méi)什么,幾乎毫 無(wú)用處,但是隨著你學(xué)習(xí)的深入,你會(huì)發(fā)現(xiàn)在Groovy里閉包無(wú)處不在.

    舉個(gè)例子,我們用Groovy來(lái)擴(kuò)展java.util.Vector類(lèi).我們添加一個(gè)方法到Vector類(lèi)里,這個(gè)方法允許你應(yīng)用閉包操作向量中的所有成員.我們新建 一個(gè)類(lèi)GVector如下,

    package ?example;

    public ? class ?GVector? extends ?java.util.Vector? {

    ??
    public ?GVector() {
    ??????
    super ();
    ??}


    ??
    public ? void ?apply(?c?) {
    ?????
    for ?(i?in? 0 .. < size()) {
    ????????
    this [i]? = ?c( this [i]);
    ?????}

    ??}

    }

    apply()方法獲得一個(gè)閉包作為輸入?yún)?shù),對(duì)于GVector中的每一個(gè)元素,閉包被調(diào)用傳遞這個(gè)元素,返回的結(jié)果值用來(lái)替換這個(gè)元素.這個(gè)思想就 是你可以使用閉包來(lái)修改GVector中的內(nèi)容,這個(gè)閉包必須能夠獲取元素并把它轉(zhuǎn)換成別的什么.
    現(xiàn)在我們就可以調(diào)用apply()方法了.你可以傳遞任意你需要的閉包給apply().例如我們新建一個(gè)GVector,設(shè)置幾個(gè)元素,然后將這些元素傳遞給
    我們上面創(chuàng)建的那個(gè)能計(jì)算整數(shù)平方的閉包.

    example.GVector?gVect? = ? new ?example.GVector();
    gVect.add(
    2 );
    gVect.add(
    3 );
    gVect.add(
    4 );

    c?
    = ? {numberToSquare? -> ?numberToSquare? * ?numberToSquare;}

    gVect.apply(c);

    // ?GVector中的所有元素全部被平方了.
    由于apply()中的閉包可以是任意的,因此你可以把任何閉包傳遞給apply().例如使用下面的這個(gè)閉包簡(jiǎn)單地把傳遞給它的元素打印出來(lái).
    example.GVector?gVect?=?new?example.GVector();
    gVect.add(
    2);
    gVect.add(
    3);
    gVect.add(
    4);

    c2?
    =?{value?->?println(value);}

    gVect.apply(c2);

    //?GVector中的元素全部被打印出來(lái).
    假設(shè)你已經(jīng)定義并編譯了GVector這個(gè)類(lèi),那么當(dāng)你運(yùn)行上面的腳本時(shí),將得到下面的結(jié)果:
    C:/>?groovy?myscript.groovy
    4
    9
    16
    C:
    />
    除了把閉包賦值給變量,你也可以直接把它聲明為方法的參數(shù).例如,上面的代碼可以重寫(xiě)為如下形式:
    example.GVector?gVect?=?new?example.GVector();
    gVect.add(
    2);
    gVect.add(
    3);
    gVect.add(
    4);

    gVect.apply?
    {value?->?println(value);}

    //?GVector中的元素全部被打印出來(lái).

    這段代碼的功能和前面的功能一樣,只不過(guò)閉包被直接定義為apply()方法的參數(shù).

    閉包VS代碼段

    閉包看上去就像正規(guī)的Java或Groovy代碼段,但是實(shí)際上他們并不相同.正規(guī)代碼段里的代碼一旦遇到就由虛擬機(jī)來(lái)執(zhí)行,閉包中花括號(hào)里的代
    碼直到call()被調(diào)用時(shí)才被執(zhí)行.上面的例子中,閉包在程序行中定義,但是當(dāng)時(shí)并不執(zhí)行.只有閉包明確的調(diào)用call()時(shí)才會(huì)被執(zhí)行.這是閉包和 代碼段的重要區(qū)別.也許他們看上去很像,但事實(shí)上兩者不同.正規(guī)的Java或Groovy代碼當(dāng)遇到時(shí)就執(zhí)行,;而閉包當(dāng)且僅當(dāng)call()被調(diào)用時(shí)才被 執(zhí)行.?

    ????????????to be continue...
    posted on 2006-04-26 17:05 學(xué)二的貓 閱讀(2544) 評(píng)論(4)  編輯  收藏 所屬分類(lèi): Groovy

    評(píng)論:
    # re: Groovy指南--(2) 閉包(非正式) 2006-04-26 22:52 | 指教了
    不是你寫(xiě)的吧?“正規(guī)代碼段里的代碼一旦執(zhí)行到就由虛擬機(jī)來(lái)執(zhí)行”,“正規(guī)的Java或Groovy代碼在執(zhí)行到時(shí)就執(zhí)行”,這些話是不是有點(diǎn)repeat廢話?呵呵  回復(fù)  更多評(píng)論
      
    # re: Groovy指南--(2) 閉包(非正式) 2006-04-26 22:52 | 指教了
    不是你寫(xiě)的吧?“正規(guī)代碼段里的代碼一旦執(zhí)行到就由虛擬機(jī)來(lái)執(zhí)行”,“正規(guī)的Java或Groovy代碼在執(zhí)行到時(shí)就執(zhí)行”,這些話是不是有點(diǎn)repeat廢話?呵呵  回復(fù)  更多評(píng)論
      
    # re: Groovy指南--(2) 閉包Closure(非正式) 2006-04-27 08:56 | 學(xué)二的貓
    @指教了
    這不是我寫(xiě)的,我翻譯自Groovy官方網(wǎng)站.
    呵呵,讓大家見(jiàn)笑了.翻譯的是有點(diǎn)業(yè)余:)
    謝謝給出批評(píng)意見(jiàn),指出翻譯錯(cuò)誤.上面你提到的我已經(jīng)修改了.
    再次謝謝大家...
      回復(fù)  更多評(píng)論
      
    # re: Groovy指南--(2) 閉包Closure(非正式) 2008-03-20 11:26 | 趙斌
    還是不錯(cuò),讓我對(duì)閉包有了一個(gè)初步的理解。
    謝謝!  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 亚洲欧美在线x视频| 日本无卡码免费一区二区三区| 午夜亚洲WWW湿好爽| 亚洲爱情岛论坛永久| 亚洲Aⅴ无码一区二区二三区软件| 97视频免费在线| 中文字幕乱码一区二区免费| 色妞www精品视频免费看| 亚洲入口无毒网址你懂的| 亚洲精品天天影视综合网| 伊人久久综在合线亚洲91| 四虎永久成人免费| 真实乱视频国产免费观看| 亚洲免费视频在线观看| 亚洲综合精品香蕉久久网| 国产最新凸凹视频免费| 拍拍拍又黄又爽无挡视频免费| 精品久久8x国产免费观看| 久久久久国产精品免费免费不卡 | 91av在线免费视频| 中文字幕在线免费看线人| 一级做a爰性色毛片免费| 久久久久亚洲av无码专区喷水| 亚洲中文久久精品无码| 亚洲国产成人爱av在线播放| 日韩精品视频免费观看| 性感美女视频免费网站午夜| 日本亚洲免费无线码| 国拍在线精品视频免费观看| 100000免费啪啪18免进| 成人免费视频69| 最新免费jlzzjlzz在线播放| 女人张腿给男人桶视频免费版| 午夜小视频免费观看| 精品免费国产一区二区三区| 日韩视频免费一区二区三区| 免费国产成人午夜私人影视| 亚洲国产精品一区二区第一页免 | 99久久婷婷国产综合亚洲| 亚洲国产视频久久| 亚洲av无码一区二区三区人妖 |