首页 > 代码库 > 《lua程序设计 第二版》 学习笔记6 -------- 深入函数

《lua程序设计 第二版》 学习笔记6 -------- 深入函数

-- 第6章 深入函数

-- 函数是一种“第一类值”,他们具有特定的“词法域”
-- “第一类值”:与其他传统类型的值具有相同的权利。例如:存储到变量/table中,作为实参传递给函数或者作为其他函数的返回值
-- "词法域":一个函数可以嵌套在另一个函数中,内部函数可以反问外部函数的变量。
local function testFun(x) return 2 * x end  -- 函数定义方式1
local testFun = function (x) return 2 * x end -- 函数定义方式2  一个变量
print(testFun(1)); 
testFun = nil;
-- 当我们讨论 print是在说一个持有某函数的变量,和一般变量是一样的
print(type(print));
local p1 = print;
local p2 = print;
p1("abc");
p1 = nil -- 指向print持有打印功能的函数 被删除
-- print = nil;    -- 指向某答应功能的函数 只剩下 p2 全局变量, print不复存在
-- 这里更变量时一样的 
p2("abc");
-- p2 = nil -- 这个时候指向控制到打印功能的函数的变量都没有了【不知道此函数会不会被回收,据说变量会】
-- 尽量保持使用local

local info = {
    {name = "salor", id = 2},
    {name = "salor3", id = 1},
    {name = "salor2", id = 3},
}


local printArray = function (table_name)
    for k,v in pairs(table_name) do
        print(k,v.name, v.id)
    end
end


printArray(info);


local function sortByName(table_name)
 table.sort(table_name, 
     function (a, b) 
         return (a.name > b.name)
     end)
end

local function sortById(table_name)
 table.sort(table_name,
    function (a, b)
        return (a.id > a.id)
    end
    )
end

sortByName(info);
printArray(info);
sortById(info);
printArray(info);


-- closure (闭合函数)
-- 函数内的另一个函数,这个函数可以访问外部函数的局部变量【词法域】
-- 见 sortByName 和 sortById 这两个函数, sort 的匿名函数可以访问外部函数的参数
-- 外部函数的参数不是一个全局变量、也不是局部变量

-- 利用上面的特性,可以做一个简单的定时器
local function newCounter()
    local i = 0;
    return function ()
        i = i + 1;-- 访问外部函数的临时变量
        return i;
    end
end

local c = newCounter()
c()
c()
print(newCounter()); 
print(c()); -- 3
local c2 = newCounter();
print(c2()); -- 1
--c1 和 c2 有不同i 和 closure ,从技术上讲,lua只有closure而不存在"函数"
-- 函数本身就是特殊的closure

--- closure 除了作为高级函数的参数,计数函数之外,它对回调函数也很有用,还可以重新定义某些存储在普通变量中的函数
do 
local oldSin = math.sin
local k = math.pi / 180
math.sin = function(x)
    return oldSin(x * k)
end
yend

-- 6.2 非全集的函数
-- 保存在table中函数
Lib = {}
Lib.foo = function (x, y) return x * y end;
function Lib.goo (x, y) return x + y end;

-- 6.3 正确的尾调用
function rAdd(x)
    if x <= 0 then
        return 1;
    else
        return x + rAdd(x -1);-- 这不是一种尾调用
end

-- function f(x) return g(x) end
-- g 调玩后返回到f,不需要保存g的任何信息,所以不需要任何栈的使用...
-- 正确的尾调用在状态机中是很重要的...
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>