您的位置:首页 > 编程语言 > Lua

lua语言-《lua程序设计》6~7章函数和迭代器与泛型for

2017-12-06 17:20 561 查看
接着上篇做的笔记,需要结合书来复习,本来准备两天通读这个近300页的pdf,现在看来我进度太慢了,前面阅读还挺快,到了这部分就 必须跟着书本写实例,才能明白基础概念。(某些用法还挺新奇的,默默感叹前辈的创造力)

11.深入函数-函数是一种“第一类值”
lua中函数与其他传统类型的值(如数字,字符串)具有相同的权利,实际是持有某个函数的变量,
可以存储在局部变量、全局变量,甚至table字段,有多种方式来操作这些变量。
示例;
a = {p=print}
a.p("hello word")   --相当于print("hello word")
sin = math.sin
a.p(sin(1))     --相当于print(math.sin(1)) ,调用正弦函数
ppp = a.p
ppp(10,20)      --相当于print(10,20)
function foo(x) return 2*x end 相当于 foo = function (x) return 2*x end ,其中“function (x) return 2*x end ”
被称为函数的构造式,就行table的构造式{}一样。函数构造式的结果称为匿名函数
高阶函数:接受另一个函数作为实参的函数
table.sort(table,匿名函数);接受一个table,并调用匿名函数对其中的元素进行排序

12. closure(闭合函数)
一个closure就是一个函数加上该函数所需访问的所有“非局部的变量”,概念示例:
function newCounter()
local i = 0
return function()
i = i+1  --匿名函数访问一个“非局部的变量”i,
--再次调用newCounter(),会创建一个新的局部变量i,从而得到新的closure
return i
end
end
c1 = newCounter()
c2 = newCounter()
print(c1()) --结果为1
print(c1()) --结果为2
print(c2()) --结果为1,同一个函数,所创建不同的closure,拥有各自独立的局部变量i的实例
由于lua函数存储在普通变量中,所以closure可以重新定义某些函数
示例
do
local oldSin = math.sin  --保存在局部变量,只有新的sin可以访问得到,属于安全的运行环境
math.sin = function(x)   --重新定义math.sin,并调用了原来的sin函数来完成计算
retrun oldSin(x*math.pi/180)
end
end
针对示例中调用原来的oldSin函数,有点疑问,又写了一段,函数存储在普通变量中,不会再跟着函数的改动而改动
function tmpfun(a,b)
return a+b
end
oldfun = tmpfun
print(oldfun(5,5))  --结果10
tmpfun = function(a,b)
return oldfun(a,b)*oldfun(a,b)
end
newfun = tmpfun
print(newfun(5,5))  --结果100
print(oldfun(5,5))  --结果10,也就是调用的还是旧版的tmpfun()

13. 非全局的函数(non-global function)
存储在table中的函数,lua库常用的手段:如io.read,math.sin
常规语法如下:
lib = {}
lib.foo = function(x,y) return x+y end
lib.goo = function(x,y) retrun x-y end
也可以用构造式
lib = {
foo = function(x,y) return x+y end
goo = function(x,y) retrun x-y end
}
还可以这样
lib = {}
function lib.foo(x,y) return x+y end
function lib.goo(x,y) retrun x-y end
使用递归函数时需要注意要先定义局部变量函数
尾调用是类似用goto的函数调用,一个函数是另一个函数的最后动作,该调用就是尾调用。
示例;
function f(x) return g(x) end
程序不需要保存任何关于该函数的栈信息,当g返回时,直接返回给调用f的地方,使尾调用时
不占用栈空间,这种实现称为“尾调用消除”。

14.迭代器-一种可以遍历集合中所有元素的机制,在lua中的将迭代器表示函数,每调用一次函数,即返回集合中下一个元素
简单示例;
function values(t)  --简单的迭代器
local i = 0
return function()  i = i +1; return t[i]  end
end
t = {10,20,30}
iter = valus(t)  --创建迭代器
while true do
local element = lter()  --调用迭代器
if element == nil then
break
end
print(element)
end
使用泛型for可以这么写,示例;
function values(t)  --简单的迭代器
local i = 0
return function()  i = i +1; return t[i]  end
end
t = {10,20,30}
for element in values(t) do  print(element) end --泛型for内部保存了迭代器函数,
--所以不需要lter变量,直到返回nil时结束循环
高级应用,输入单词并遍历所有单词打印,示例:
function allwords()
local line = io.read() --输入的数据存放在table中
local pos = 1
return function()
while line do
local s,e = string.find(line,"%w+",pos) --找单词
if s then --是否找到单词
pos = e + 1 --该单词的下一个位置
return string.sub(line,s,e) --返回该单词【迭代器的使用中,主要看返回值】
else
line = io.read()
pos = 1
end
end
return nil
end
end
for word in allwords() do  --使用迭代器很简单
print(word)
end
15.泛型for -运行过程中实际保存三个值:迭代器函数,恒定状态,控制变量
语法如下:
for <var-list> in <exp-list> do
<执行代码>
end
<var-list> 是一个或多个变量名的列表,逗号分隔
<exp-list>是一个或多个表达式列表(通常为迭代器工程的调用),逗号分隔,
表达式返回三个值供for保存:迭代器函数,恒定状态,控制变量,多余丢弃,不足补nil,
如果第一个返回值为nil,那么循环终止。否则for执行循环体,随后再次调用迭代器函数,重复过程

16.无状态的迭代器-自身不保存任何状态的迭代器,避免创建新的closure开销
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lua 迭代器 语言 泛型