码迷,mamicode.com
首页 > 其他好文 > 详细

第六章 深入理解函数 Lua程序设计笔记

时间:2017-11-26 14:01:54      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:body   forward   new   print   不同的   案例   相同   roo   前向声明   

--第六章 深入理解函数
Lua中函数是“第一类值”,与其他传统类型有相同的权利:
可以储存到变量或table中,可以作为函数实参传递,还可以作为函数的返回值。

函数的标准定义:

foo = function(x) return x*2 end

一个函数定义实际上就是一条赋值语句,这条语句创建了一种类型为“函数”的值,并将这个值赋予一个变量。

 

 

--6.1closure(闭合函数)

function newCounter()
local i = 0
return function()
        i = i + 1
        return i
    end
end


非局部的变量(non-local variable):
是外部函数的局部变量,在内部的匿名函数中,既不是局部也不是全局变量。如上面的i。
一个closure就是一个函数加上该函数所需访问的所有“非局部的变量”。
c1和c2是同一个函数创建的两个不同的closure,它们各自拥有局部变量i的独立实例。

c1 = newCounter()
print(c1()) -->1
print(c1()) -->2
c2 = newCounter()
print(c2()) -->1
print(c1()) -->3
print(c2()) -->2

 

 

--6.2非全局函数
一个错误的示例:

local fact = function(n)
    if n == 0 then return 1
    else return n * fact(n-1)
    end
end

当编译到函数体中调用fact(n-1)时,由于局部fact尚未定义完毕,因此这个语句其实调用了一个全局的fact。

正确的写法:

local fact 
fact = function(n)
    if n == 0 then return 1
    else return n * fact(n-1)
    end
end

现在函数中的fact调用就表示局部变量。

 

使用语法糖

local function foo() <body> end

Lua将其展开为:

local foo
foo = function() <body> end

因此使用语法糖可以直接定义递归:

local function fact(n)
    if n == 0 then return 1
    else return n*fact(n-1)
    end
end

但是对于间接递归,必须使用明确的前向声明(forward declaration)

local f,g
function g()
    ... f() ...
end
function f()
    ... g() ...
end

 

 

--6.3正确的尾调用(tail call)
当一个函数调用的是另一个函数的最后动作是,才是一条尾调用:

function f(x) return g(x) end

不是尾调用的示例:

function f(x) g(x) end --调用完g后,f并不能立即返回,而还需要丢弃g返回的临时结果
return g(x) + 1   --还要做一个加法
return x or g(x)  --还要调整为一个返回值
return (g(x))     --还要调整为一个返回值

一个尾调用就好比一个goto语句,迷宫游戏的案例:

function room1()
    local move = io.read()
    if move == "south" then return room3() 
    elseif move == "east" then return room2()
    else print("invalid move") return room1()
    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("congratulations!")
end

通过调用room1()进入游戏

第六章 深入理解函数 Lua程序设计笔记

标签:body   forward   new   print   不同的   案例   相同   roo   前向声明   

原文地址:http://www.cnblogs.com/leosirius/p/7898745.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!