Lua学习笔记Day2

一:函数

1.Lua中的函数是带有词法界定的第一类值。第一类值是指在Lua中函数和其他值一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。词法界定是指嵌套的函数可以访问其他外部函数中的变量。

1.1闭合函数:指一个函数加上该函数所需访问的所有“所有非局部的变量”(也可称为外部的局部变量 upvalue).如下面例子的i,就是非局部变量.

function count()
  local i = 1--非局部变量 不会被重置 在上次的基础上--
  return function()
            i=i+1
            return i
         end
end

local func = count()
print(func())     --2--
print(func())     --3--

1.2非全局函数:使用local定义的函数。需要注意当一个函数要使用另一个非全局函数时,应要前向声明,否则报错。

local test1;
--非全局函数--
local function test()
  print(123)
  --test1()--
  test1() --需要前置声明 见29行
end


test1 = function(...)
          print(123)
        end

--test调用--
test()
1.3尾调用:类似在函数结尾的goto调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用为尾调用。
local lfunc;
local pfunc;
lfunc = function()
  print("lfunc")
end

function pfunc()
  return lfunc();
end

print(pfunc())

二:迭代器与泛型for

2.1迭代器是一种指针类型的结构,它可以遍历集合的每一个元素。在Lua中常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素。

迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是它知道来自于哪里以及将要去往哪里。闭包提供的机制可以很容易实现这个任务。

*闭包是一个内部函数,它可以访问一个或者多个外部函数的外部局部变量每次闭包的成功调用后外部局部变量都保存他们的值(状态)。当然如果要创建一个闭包必须要创建其外部局部变量。所以一个典型的闭包的结构包括两个函数:一个是闭包自己;另一个是工厂(创建闭包的函数)。

--[[迭代器的实现--]]
function iteratorFun(t)
  local i = 0
    return function()
      i = i + 1
      return t[i]
    end
end

t = {1,2,3}
--[[
local func = iteratorFun(t)--避免iteratorFun(t)()每次都会初始化--
print(func())
print(func())
--]]
function forFun(t)
local iter = iteratorFun(t);--返回函数指针--
print(iter)
  while true do
    local value = iter()
   if value == nil then
     break;
    end
    print(value)
  end
end

--[[也可直接用for in 直接输出值--]]
for value in iteratorFun(t) do
  print(value)
end

a = {"hello","my","darling","how are you"}
--[[forFun(a)--]]

--返回两个值的迭代器--
function dieDaiQi(a)
  local i = 0
  return function()--尾调函数--
    i = i+1
    if i > #a then
      return nil;
    end
    return i,a[i]
  end
end


print("打印结果:")
for k,v in dieDaiQi(a) do
  print(k,v)
end


print("*******************for in do****************")
--for in do
function forInDo(t)
  --_f迭代器函数 _s恒定状态 _var控制变量初始值
  local _f,_s,_var = dieDaiQi(t)
  while true do
    local k , v = _f(_s,_var)
    _var = k;
    if(_var == nil) then
      break;
      end;
      print(k..":"..v)
  end
end

forInDo(a)

四:协同程序

4.1协同程序(coroutine)与多线程情况下的线程比较类似:有自己的堆栈,自己的局部变量,有自己的指令指针(IP),但与其他协同程序共享全局变量等很多信息。线程和协同程序的主要不同在于:在多处理器情况下,从概念上来讲多线程程序同时运行多个线程;而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起。

4.2Lua所有的协同函数都存放在coroutinue table中。create函数用于创建新的协同程序,其只有一个参数:一个函数,即协同程序将要运行的代码。若一切顺利,返回值为thread类型,表示创建成功。通常情况下,create的参数是匿名函数:

--协同程序 默认挂起状态--
local co = coroutine.create(function()
	print("coroutine")
	end)
print(co)	-->返回thread类型 输出为 thread:006FFE70
4.3协同有三个状态:挂起(suspended) 、运行(running)、终止(dead)。当我们创建协同程序成功时,其为挂起太,即此时协同程序并未运行。我们可以用status函数来检查协同的状态。

4.4函数coroutine.resume使协同程序由挂起态变为运行态,当完成相应的功能后,任务完成,便进入终止态(dead)。

cortinue.resume(co) -->coroutine

print(coroutine.status(co)) -->dead

4.5协同真正的强大之一在于yield函数,它可以将正在运行的代码挂起。当我们激活被挂起的程序时,将从函数yield的位置继续执行程序,知道再次遇到yield或程序结束。如果在最后一次调用时,即协同程序处于终止态,若我们仍然希望激活它时,resume将返回false和错误信息。

注:resume运行在保护模式下,因此,如果协同程序内部存在错误,Lua并不会抛出错误,而是将错误返回给resume函数。

4.6协同的强大之二在于可以通过resume-yield来交换数据。

1)resume除第一个参数外后面的实参可以传递给create函数中的匿名函数的形参中去。

co = coroutine.create(function (a,b,c)

    print("co", a,b,c)

end)

coroutine.resume(co, 1, 2, 3)      --> co  1  2  3

2)数据可由yield传给resume。resume有两个返回值,若调用成功,则第一个返回值为true,第二个错误信息则为yiedf的参数。

3)数据可由resume的参数传递给yield,即yield的返回值为resume的参数。

--[[
	①resume的实参传递给create回调函数的形参
	②yield函数的参数可以传递到resume的第二个返回值
--]]
print("************resume的实参传递给create回调函数的形参****************")
local co3 = coroutine.create(function(param)
	print(param)
	coroutine.yield("yield函数的参数[测试是否可以传给resume的第二个返回值]")
	end)
local result,msg = coroutine.resume(co3,"param");
print("co3 result:",result)
print("co3 msg:",msg)

--[[③yield函数的返回值是resume的第二个参数

--]]
local co4 = coroutine.create(function(name)
	for i = 1,2,1 do
		print(name)
		local result = coroutine.yield("yield函数的参数")
		print("yield函数的返回值:",result)-->yield的返回值为name2
	end
	end)
local result1,error1 = coroutine.resume(co4,"name1")
local result2,error2 = coroutine.resume(co4,"name2")
print("co4_1 result1:",result1,"   ","co4_1 error1:",error1)
print("co4_2 result2:",result2,"   ","co4_2 error2:",error2)
print("status:",coroutine.status(co4))--执行了两次挂起 所以还是挂起状态 需要再执行一次就dead状态







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值