• <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>
            ::^喬喬^::明鏡臺::原創空間::C#.NET2.0,C++技術BLOG
            人最重要的是心境,一顆平靜安穩的心才能更好的進步,保持自己的心態.成為夢想中的高手QQ群:8664695
            posts - 17,comments - 32,trackbacks - 0

            1、lua學習之入門(一)----環境搭建

            2、lua學習之入門(二)----基礎語法1

            3、lua學習之入門(二)----基礎語法2

            4、lua學習之入門(三)----函數

            ???? 在LUA里函數是個十分重要的內容,因為我們實際開發的時候,用的最多的就是函數,用函數是封裝各個實現,在Q群里曾經聽一些大蝦說過,寫LUA必須要懂得閉包,常用系統函數,還有范型for寫迭代器,最后就是編譯和運行還有錯誤信息.其實這章,我就卡了一下殼,卡殼的地方在閉包,因為我沒有完全理解閉包的作用,和閉包的好處,網上也沒有明確的說明閉包的優劣,所以閉包的概念,我也只能以個人感覺去寫,如果我說得不對,歡迎賜教.如果對閉包理解很深,歡迎來指教...你要偶拜你為師也行,達者為師啊,偶很好學的.

            函數有兩種用途:1.完成指定的任務,這種情況下函數作為調用語句使用;2.計算并返回值,這種情況下函數作為賦值語句的表達式使用。

            ?? 其實我們接觸最早的,就是函數,還記得我們的第一個LUA嗎?print();這就是一個函數.可以理解****()都可以當做是函數,其實大部分編程語言的函數都是以這個方式一共調用的.認識了什么是函數,那么我們就自己編寫一個函數吧

            function?maxFun(a , b)
            ???
            if ?a > b?then
            ???
            return ?a;
            ???
            else
            ?????
            return ?b;
            ??end
            end

            -- 我們用一個輸出語句把我們的函數結果顯示出來 , 證明我們寫的函數沒有問題

            print (maxFun( 4 , 3 ));
            上面這個函數
            , 其實很簡單就是比較兩個數的大小 . 最后運行的結果我們得到結果是4 , 這里使用的是函數的第1種任務 , 判斷兩個數的大小 , 在LUA里函數是可以返回多個值的 , 這個點和其他編程語言有很大的區別 , 那就很容易造成錯覺 , 多個返回值 , 那我如何獲得各個返回值呢 ? 看例子

            function?returnAnyValue()
            ????????
            return ? 1 , 2 , 3 , 4 ;
            ???end

            ????a
            , b , c , d? = ?returnAnyValue();
            e
            , f , g? = ?returnAnyValue();
            h
            , i , j , k , l? = ?returnAnyValue();

            -- [[
            print ( " a: " .. a .. " ?b: " .. b .. " ?c: " .. c .. " ?d: " .. d .. " ?e: " .. e .. " ?f: " .. f .. " ?g: " .. g .. " ?h: " .. h .. " ?i: " .. i .. " ?j: " .. j .. " ?k: " .. k .. " ?l: " .. l .. " ?! " );
            ]]
            -- 這樣編譯是出錯的 , 提示告訴我們l為nil不能輸出 .

            -- 所以我們把程序修改為

            print ( " a: " .. a .. " ?b: " .. b .. " ?c: " .. c .. " ?d: " .. d .. " ?e: " .. e .. " ?f: " .. f .. " ?g: " .. g .. " ?h: " .. h .. " ?i: " .. i .. " ?j: " .. j .. " ?k: " .. k .. " ?! " );

            結果如下
            :
            ???a
            : 1 ?b : 2 ?c : 3 ?d : 4 ?e : 1 ?f : 2 ?g : 3 ?h : 1 ?i : 2 ?j : 3 ?k : 4


            雖然我們不能輸出L的值,但是我們根據錯誤提示可以知道l的值是nil的.

            論述完返回值,那么我們要看參數數了,LUA支持可變參數的模式的使用的方法和C語言的差不多,不熟悉的可以先學C語言,畢竟我看到的LUA大多數都是嵌入C中的,所以C/C++至少你要會.

            好了我們要進入我覺得比較難的點:閉包

            在我接觸的編程語言里,其實還沒發現過閉包的概念,坦白的說一句,就是LUA我才接觸閉包的.閉包從網上的資料來看,就是JAVASCRIPT里的匿名函數的使用(我接觸新語言的時候,總喜歡用自己接觸過的語言去進行對比,去學習.我覺得這種學習的方法還是比較有效果的,有興趣的朋友也可以試試這個方法.),在我看了網上公開的閉包程序,最大的特點就是使用,外面的函數有自己的局部變量,內部的匿名函數使用了外部函數的局部變量.有點像面向對象思想里的意思,后來我在LUA的一個論壇看到一篇關于閉包的定義,如下:

            當一個函數內部嵌套另一個函數定義時,內部的函數體可以訪問外部的函數的局部變量,這種特征我們稱作詞法定界。雖然這看起來很清楚,事實并非如此,詞法定界加上第一類函數在編程語言里是一個功能強大的概念,很少語言提供這種支持。
            技術上來講,閉包指值而不是指函數,函數僅僅是閉包的一個原型聲明

            這個是我在網上找的一個關于閉包的例子,個人感覺水平有限.可能使用網上的例子更有說服力

            下面看一個簡單的例子,假定有一個學生姓名的列表和一個學生名和成績對應的表;現在想根據學生的成績從高到低對學生進行排序,可以這樣做:

            names?
            = ?{ " Peter " , ? " Paul " , ? " Mary " }

            grades?
            = ?{Mary? = ? 10 , ?Paul? = ? 7 , ?Peter? = ? 8 }

            table
            . sort (names , ?function?(n1 , ?n2)

            ????
            return ?grades[n1]? > ?grades[n2]???? -- ?compare?the?grades

            end)
            假定創建一個函數將上面的功能包裝起來

            ???function sortbygrade (names, grades)

            ?? ??? table.sort(names, function (n1, n2)

            ????????? return grades[n1] > grades[n2]??? -- compare the grades

            ??? end)

            end
            例子中包含在sortbygrade函數內部的sort中的匿名函數可以訪問sortbygrade的參數grades,在匿名函數內部grades不是全局變量也不是局部變量,我們稱作外部的局部變量(external local variable)或者upvalue。(upvalue意思有些誤導,然而在Lua中他的存在有歷史的根源,還有他比起external local variable簡短)。


            這個例子主要說明的是在外部函數和內部函數之見參數的使用,函數中就可以直接用變量進行傳值,這里需要說明一下的是table.sort(存放元素的數組,排序函數)具體的等后面我介紹常用庫的時候說.只要知道是表排序就好.

            函數就寫出來的,但是我們需要更直觀的看到這些資料
            所以我在最下面加上了如下代碼

            print ( " --------- " )
            sortbygrade?(names
            , ?grades);

            for ?v?in?pairs(names)? do

            print (names[v])
            end
            輸出結果為
            Mary
            Peter
            Paul
            我將grades = {Mary = 7, Paul = 8, Peter = 9}改了再看效果
            Peter
            Paul
            Mary

            function?newCounter()

            ????
            local?i?=?0

            ????
            return?function()?????--?anonymous?function

            ???????i?
            =?i?+?1

            ????????
            return?i

            ????end

            end

            ?

            c1?
            =?newCounter()

            print(c1())??-->?1

            print(c1())??-->?2

            print(c1())??-->?3

            結果代碼里已經顯示了,我就不說了,但是大家看到這個結果?你想到了什么?
            對象?就是對象,看以下C#代碼
            public?class?CC
            {
            ????
            private?int?a;

            ????
            public?CC()
            ????
            {
            ???????a
            =0;
            ????}


            ????
            public?int?newCounter()
            ????
            {
            ???????
            this.a=this.a+1;
            ???????retrun?
            this.a;
            ????}

            }

            如果LUA代碼里C1=newCounter();C2=newCounter()
            ?print(c2())--->1
            是不是跟我們聲明一個對象十分的類似呢?所以我推斷閉包在一定程度上實現了部分面向對象的功能,肯定有一定的差別的,我只是說類似..而且我看代碼有點像C語言去實現面向對象的感覺...

            閉包還可以實現類似JAVA里沙箱的功能,(來自網上,我并沒有運行這段代碼)
            do

            ????local?oldOpen?
            =?io.open

            ????io.
            open?=?function?(filename,?mode)

            ???????
            if?access_OK(filename,?mode)?then

            ???????????
            return?oldOpen(filename,?mode)

            ???????
            else

            ???????????
            return?nil,?"access?denied"

            ???????
            end

            ????
            end

            end

            *正確的尾調用
            這個迷宮游戲是典型的狀態機,每個當前的房間是一個狀態。我們可以對每個房間寫一個函數實現這個迷宮游戲,我們使用尾調用從一個房間移動到另外一個房間。一個四個房間的迷宮代碼如下:

            function?room1?()

            ????local?move?
            =?io.read()

            ????
            if?move?==?"south"?then

            ???????
            return?room3()

            ????elseif?move?
            ==?"east"?then

            ???????
            return?room2()

            ????
            else

            ???????
            print("invalid?move")

            ???????
            return?room1()???--?stay?in?the?same?room

            ????
            end

            end

            ?

            function?room2?()

            ????local?move?
            =?io.read()

            ????
            if?move?==?"south"?then

            ???????
            return?room4()

            ????elseif?move?
            ==?"west"?then

            ???????
            return?room1()

            ????
            else

            ???????
            print("invalid?move")

            ???????
            return?room2()

            ????
            end

            end

            ?

            function?room3?()

            ????local?move?
            =?io.read()

            ????
            if?move?==?"north"?then

            ???????
            return?room1()

            ????elseif?move?
            ==?"east"?then

            ???????
            return?room4()

            ????
            else

            ???????
            print("invalid?move")

            ???????
            return?room3()

            ????
            end

            end

            ?

            function?room4?()

            ????
            print("congratilations!")

            end

            我們可以調用room1()開始這個游戲。

            如果沒有正確的尾調用,每次移動都要創建一個棧,多次移動后可能導致棧溢出。但正確的尾調用可以無限制的尾調用,因為每次尾調用只是一個goto到另外一個函數并不是傳統的函數調用
            (以上代碼來源網上)
            正確尾調用論述的意義在于..棧溢出的問題,不正確的尾調用是存在棧溢出問題的.

            這篇寫的我自己都不是很滿意...因為這個東西..需要點時間消化...等我消化了再來整理一下,就好象開頭,我也是一個LUA新手,我只能把我認識的弄出來,而且正確上..也非絕對..其實我的目的只是傳播我的學習的思想.

            明鏡臺
            posted on 2009-05-14 13:14 ^喬喬^ 閱讀(2084) 評論(0)  編輯 收藏 引用 所屬分類: Lua學習筆記
            久久精品国产亚洲av影院| 久久人人爽人人爽人人爽| 97久久国产综合精品女不卡| 久久久久无码精品| 久久99精品久久久久久不卡| 久久亚洲国产精品123区| 亚洲精品美女久久久久99小说 | 国产免费福利体检区久久| 国产精品女同一区二区久久| 亚洲国产婷婷香蕉久久久久久| 少妇无套内谢久久久久| 久久夜色精品国产噜噜亚洲AV| 久久精品国产精品青草app| 无码任你躁久久久久久| 久久se精品一区精品二区| 亚洲国产高清精品线久久 | 久久精品人人槡人妻人人玩AV| 2021久久精品国产99国产精品| 无码任你躁久久久久久| 热re99久久精品国99热| 热RE99久久精品国产66热| 99久久99久久精品免费看蜜桃| 亚洲精品高清一二区久久| 91精品久久久久久无码| 99re这里只有精品热久久| 三级韩国一区久久二区综合| 99久久精品国产综合一区| 波多野结衣中文字幕久久| 久久久久国产精品嫩草影院| 久久综合中文字幕| 精品免费tv久久久久久久| 久久人妻无码中文字幕| 中文成人无码精品久久久不卡| 久久精品无码一区二区日韩AV| 久久久久成人精品无码中文字幕| 亚洲国产精品成人久久蜜臀| 国内精品久久久久久久涩爱| 情人伊人久久综合亚洲| 久久免费小视频| 国产视频久久| 久久99精品免费一区二区|