lua基础语法1(迭代器,变量,点与冒号等)

转载自:lua程序设计

 

lua语法学习:


1,Lua 变量有三种类型:全局变量、局部变量、表中的域。
Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量。
局部变量的作用域为从声明位置开始到所在语句块结束。
变量的默认值均为 nil。local tmp print(tmp)--nil
应该尽可能的使用局部变量,有两个好处:
1. 避免命名冲突。
2. 访问局部变量的速度比全局变量更快。

a = {}  a.a = 10  a.b = 20  a["xx"] = 30
print(a.b,a['a'],a.xx)

2,泛型for循环通过一个迭代器函数来遍历所有值,类似java中的foreach语句。
a={"Hello","World",a=1,b=2,"Good","Bye"}
for i,v in ipairs(a) do
  print(i,v)
end

3,lua 中pairs 和 ipairs区别
迭代table元素的(pairs),迭代数组元素的(ipairs)
pairs:可以遍历表中所有的key,不能返回nil,因为表中的nil等于没有元素
ipairs:按顺序遍历表中为整数的key,如果这个顺序中断,那后面的就不会再打印,比如:1,2,4只会打印1,2不会打印4。不能返回nil,因为表中的nil等于没有元素
pairs 和 ipairs取值表现还是要看{}表是如何处理里面的元素的。
在Lua中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。
a1 = {"1",[2]="rr",xx=3,[4]=3} 打印如下:
1    1
2    rr
4    3
xx    3
a1 = {[2]="1","rr",xx=3,[4]=3} 打印如下:
1    rr
2    1
4    3
xx    3
a1 = {[1]="1","rr",xx=3,[4]=3,"Good"} 打印如下:
1    rr
2    Good
4    3
xx    3
"1"没有了???
由上面的打印可以推测,表中的元素如果没有key,则会自动为其按照1234顺序设置key值,字符串如果没有key,会自动设置key值,如果有超过3个字符时,就要小心为字符串设置key值,否则会导致字符串被覆盖。
a1 = {["1"]="1","rr",xx=3,[4]=3,[3]="Good"} 打印如下:
1    rr
3    Good
4    3
1    1
xx    3
由此猜想(纯属猜想):表会默认先为没有key的字符串设置key值,然后再判断是否有设置好的key值,最后再排序那些有key值但是又不是整数数字的key的值,且优先排序字符串。

另一个循环,相当于do while
i = 1
repeat 
  print(i)
  i = i + 1
until(i>10)

Lua认为false和nil为假,true和非nil为真。要注意的是Lua中 0 为 true:
可变参数:
function fun(...)
  local a = {...}
  local tmp = 0
  for i,v in ipairs(a) do
    tmp = tmp + v
  end
  print('平均数'..tmp/#a)
end

fun(1,2,3,4,5)

通常在遍历变长参数的时候只需要使用 {…},然而变长参数可能会包含一些 nil,那么就可以用 select 函数来访问变长参数了:
select('#', …) 返回可变参数的长度
select(n, …) 用于访问 n 到 select('#',…) 的参数,返回的是n到表末的数据,赋值的话就取第一个,赋值给表也一样,这里有疑问???。
function fun(...)
  print(select('#',...))--打印长度为5
  for i=1,select('#',...),1 do
    local tmp = select(i,...) --返回的是i到表末的数据,赋值的话就取第一个
    print(tmp) --依次打印出1,2,3,4,5
    print(select(i,...)) --依次打印出1,2,3,4,5;2,3,4,5;3,4,5;4,5;5
  end
end
fun(1,2,3,4,5)
#:一元运算符,返回字符串或表的长度。
http://www.runoob.com/lua/lua-strings.html 字符串的库函数,及例子

Lua迭代器:
在Lua中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。
泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。Lua 默认提供的迭代函数 ipairs。
for k, v in pairs(t) do --k, v为变量列表;pairs(t)为表达式列表。
    print(k, v)
end
上面代码的执行过程:
1,计算in后面表达式的值(即pairs(t)),表达式应该返回泛型 for 需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略。
2,将状态常量和控制变量作为参数调用迭代函数(注意:对于for结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。
3,将迭代函数返回的值赋给变量列表。k, v为变量列表。如果返回的第一个值为nil循环结束,否则执行循环体。回到第2步再次调用迭代函数,猜想:将k的值传入作为参数(控制变量),因为无状态迭代器应该是固定格式。
如下代码:
function fun(maxindex,index)--迭代函数fun、状态常量maxindex、控制变量index
    if index < maxindex then
      index = index + 1
      return index,index*index --迭代函数fun返回的值赋给变量列表,即k,v
    end
end
--迭代函数fun、状态常量3、控制变量0,迭代函数fun返回的值赋给变量列表,即k,v
for k,v in fun,3,0 do 
  print(k,v)
end

在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素。Lua 的迭代器包含以下两种类型:无状态的迭代器(比如:ipairs),多状态的迭代器.
1,无状态的迭代器:
无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。
每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。
实现一个ipairs如下:
function tmp_ipairs(arr,index)
  index = index + 1
  if arr[index] then
    return index,arr[index]
  end
end
function my_ipairs(arr) 
  return tmp_ipairs,arr,0
end
--my_ipairs({"aa","bb","cc"})会展开成 tmp_ipairs,arr,0。其中arr,0是tmp_ipairs的参数
--tmp_ipairs按照相应的条件返回k,v 的值
for k,v in my_ipairs({"aa","bb","cc"}) do 
  print(k,v)
end
如果只需要value,那只返回value也可以:
index = 0
function tmp_ipairs(arr)
  index = index + 1
  if arr[index] then
    return arr[index]
  end
end
function my_ipairs(arr) 
  return tmp_ipairs,arr
end
for v in my_ipairs({"aa","bb","cc"}) do 
  print(v)
end
上面在改写时出了一个错误:
猜想:在第2次执行时,将k的值传入作为参数(控制变量),因为无状态迭代器应该是固定格式。先打印aa,然后报的错误为:'index' (a string value)应该是bb作为index(控制变量)的值传入函数了。

2,多状态的迭代器:
很多情况下,迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,还有一种方法就是将所有的状态信息封装到table内,将table作为迭代器的状态常量,因为这种情况下可以将所有的信息存放在table内,所以迭代函数通常不需要第二个参数。
代码如下:
function fun(arr)
  local index = 0
  local count = #arr
  return function()
    index = index + 1
    if index <= count then
      return arr[index] --返回value值,key不要了
    end
  end
end
arr= {"aa",44,"bb"}
for v in fun(arr) do 
    print(v)
end

lua点与冒号的区别:
1、定义的时候:myTable:fun()与 myTable.fun(self)是等价的,点号(.)要达到冒号(:)的效果要加一个self参数到第一个参数;
2、调用的时候:myTable:fun() 与myTable.fun(object)等价,点号(.)要添加对象自身到第一个参数。
myTable = {}
myTable.num = 100
function myTable.fun(self)
  print("i am fun "..self.num)
end
myTable.fun(myTable)
myTable:fun()
--myTable.fun()--打印错误
--myTable.fun(self)--打印错误
 

闭包:
当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征我们称作词法定界。

局部函数:当我们将函数保存在一个局部变量内时,我们得到一个局部函数,也就是说局部函数像局部变量一样在一定范围内有效。
局部变量是存放在lua的堆栈里面的是array操作,而全局变量是存放在_G中的table中,效率不及堆栈。如果被多次执行调用的全局变量,就需要考虑用local来申明 

lua删除表和C#里删除容器元素一样,都会立刻重置容器,所以需要从后往前删除
for i=#myTable,1,-1 do
  if myTable[i] == 3 or myTable[i] == 4 then
    table.remove(myTable,i)
  end
end

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值