加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua学习笔记

发布时间:2020-12-14 22:12:37 所属栏目:大数据 来源:网络整理
导读:lua中交换变量的值: 遇到赋值语句 Lua 会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值:? x,y = y,x -- swap 'x' for 'y'? a[i],a[j] = a[j],a[i] -- swap 'a[i]' for 'a[i]'? repeat-until 语句: repeat statements; until cond

lua中交换变量的值:

遇到赋值语句 Lua会先计算右边所有的值然后再执行赋值操作,所以我们可以这样进行交换变量的值:?

x,y = y,x-- swap 'x' for 'y'?

a[i],a[j] = a[j],a[i]-- swap 'a[i]' for 'a[i]'?


repeat-until语句:

repeat

 statements; until conditions;

关于for语句

for 语句有两大类:第一,数值 for循环:

for 将用 exp3作为 stepexp1(初始值)到exp2(终止值),执行loop-part。其中exp3可以省略,默认 step=1

有几点需要注意:
1. 三个表达式只会被计算一次,并且是在循环开始前。

for var=exp1,exp2,exp3 do
   loop-part

end

for i=1,f(x) do print(i)

end

for i=10,1,-1 end

第一个例子 f(x)只会在循环前被调用一次。


2. 控制变量 var是局部变量自动被声明,并且只在循环内有效.

如果需要保留控制变量的值,需要在循环中将其保存
end

max = i       -- probably wrong! 'i' here is global
-- find a value in a list
local found = nil
for i=1,a.n do

ifa[i] == valuethen
found = i-- save value of 'i'

break

end

end

print(found)

3. 循环过程中不要改变控制变量的值,那样做的结果是不可预知的。如果要退出循

环,使用 break语句。?


第二,范型 for循环:

前面已经见过一个例子:

范型 for遍历迭代子函数返回的每一个值。再看一个遍历表key 的例子:

范型 for和数值 for有两点相同:

1. 控制变量是局部变量
2. 不要修改控制变量的值再看一个例子,假定有一个表:

现在想把对应的名字转换成星期几,一个有效地解决问题的方式是构造一个反向表:

revDays = {["Sunday"] = 1,["Monday"] = 2,0.000000%)">"Tuesday"] = 3,0.000000%)">"Wednesday"] = 4,

["Thursday"] = 5,0.000000%)">"Friday"] = 6,0.000000%)">"Saturday"] = 7}下面就可以很容易获取问题的答案了:

  我们不需要手工,可以自动构造反向表

如果你对范型 for还有些不清楚在后面的章节我们会继续来学习。


-- print all values of array 'a'
for i,v in ipairs(a) do print(v) end
-- print all keys of table 't'
for k in pairs(t) do
  print(k)?
end
days = {"Sunday","Monday",0.000000%)">"Tuesday",0.000000%)">"Wednesday",0.000000%)">              "Thursday",0.000000%)">"Friday",0.000000%)">"Saturday"}

x = "Tuesday"

print(revDays[x])--> 3

revDays = {}
in ipairs(days) do
   revDays[v] = i

end?


break return 语句
break 语句用来退出当前循环(for,repeat,while)。在循环外部不可以使用。

return 用来从函数返回结果,当一个函数自然结束结尾会有一个默认的 return。(这种函数类似 pascal 的过程)

Lua 语法要求 break return 只能出现在 block 的结尾一句(也就是说:作为 chunk的最后一句,或者在 end 之前,或者 else 前,或者 until 前),例如:

有时候为了调试或者其他目的需要在 block 的中间使用 return 或者 break,可以显式的使用 do..end 来实现:

local i = 1 while a[i] do
   if a[i] == v then break end

i=i+1

function foo ()
return --<< SYNTAX ERROR
-- 'return' is the last statement in the next block

do return end -- OK
... -- statements not reached

end?


关于函数返回多个结果值

Lua 函数可以返回多个结果值,比如 string.find,其返回匹配串“开始和结束的下标”

(如果不存在匹配串返回 nil)。?

Lua 总是调整函数返回值的个数去适用调用环境,当作为一个语句调用函数时,所有返回值被忽略。假设有如下三个函数:

function foo0 () end-- returns no results

function foo1 () return 'a' -- returns 1 result

function foo2 () return 'a','b' -- returns 2 results

第一,当作为表达式调用函数时,有以下几种情况:
1. 当调用作为表达式最后一个参数或者仅有一个参数时,根据变量个数函数尽可能

多地返回多个值,不足补 nil,超出舍去。
2. 其他情况下,函数调用仅返回第一个值(如果没有返回值为 nil)

 
         
x,y = foo2()-- x='a',y='b'
x = foo2()
x,y,z = 10,foo2()-- x=10,y='a',z='b'
x,y = foo0()-- x=nil,y=nil
x,y = foo1()
x,z = foo2()

x,y = foo2(),20 -- x='a',y=20
x,y = foo0(),20,30 -- x='nil',y=20,30 is discarded

第二,函数调用作为函数参数被调用时,和多值赋值是相同。

print(foo0())-->

print(foo1())--> a?

print(foo2())-->a b?

print(foo2(),1)-->a 1?

print(foo2() .. "x")?--> ax?


第三,函数调用在表构造函数中初始化时,和多值赋值时相同。
a = {foo0()}-- a = {} (an empty table)
a = {foo1()}-- a = {'a'}
a = {foo2()}-- a = {'a','b'}a = {foo0(),foo2(),4} -- a[1] = nil,a[2] = 'a',a[3] = 4?

另外,return f()这种类型的返回 f()返回的所有值?

function foo (i)
   if i == 0 then return foo0()
   elseif i == 1 then return foo1()
   elseif i == 2 then return foo2()
   end

end

print(foo(1))--> a
print(foo(2))--> a b
print(foo(0))-- (no results)
print(foo(3))-- (no results)
可以使用圆括号强制使调用返回一个值。
print((foo0()))--> nil
print((foo1()))--> a
print((foo2()))--> a

一个 return 语句如果使用圆括号将返回值括起来也将导致返回一个值。

函数多值返回的特殊函数 unpack,接受一个数组作为输入参数,返回数组的所有元素。unpack 被用来实现范型调用机制,在 C 语言中可以使用函数指针调用可变的函数,可以声明参数可变的函数,但不能两者同时可变。在 Lua 中如果你想调用可变参数的可变函数只需要这样:


         
         
f(unpack(a))

unpack 返回 a 所有的元素作为 f()的参数

f = string.find
a = {
"hello",?"ll"}print(f(unpack(a)))?--> 3 4

预定义的 unpack 函数是用 C 语言实现的,我们也可以用 Lua 来完成:

function unpack(t,i) i = i or 1
   if t[i] then
       return t[i],unpack(t,i + 1)

endend?


可变参数?

Lua 函数可以接受可变数目的参数,和 C 语言类似在函数参数列表中使用三点(...)表示函数有可变的参数。Lua 将函数的参数放在一个叫 arg 的表中,除了参数以外,arg表中还有一个域 n 表示参数的个数。

例如,我们可以重写 print 函数:

printResult = ""
function print(...)
   for i,100.000000%)">in ipairs(arg) do
       printResult = printResult .. tostring(v) .. "t"
   end
   printResult = printResult .. "n"
end
有时候我们可能需要几个固定参数加上可变参数
function g (a,b,...) end

CALL PARAMETERS

g(3) a=3,b=nil,arg={n=0} g(3,4) a=3,b=4,4,5,8) a=3,arg={5,8; n=2} 

举个具体的例子,如果我们只想要 string.find 返回的第二个值:

一个典型的方法是使用虚变量(下划线)

local _,x = string.find(s,p)
-- now use `x'
...

还可以利用可变参数声明一个 select 函数:

function select (n,...)
return arg[n]

end

print(string.find("hello hello",0.000000%)">" hel")) --> 6 9

print(select(1,string.find(" hel"))) --> 6

print(select(2,0.000000%)">--> 9

有时候需要将函数的可变参数传递给另外的函数调用,可以使用前面我们说过的unpack(arg)返回 arg 表所有的可变参数,Lua 提供了一个文本格式化的函数 string.format(类似 C 语言的 sprintf 函数):

function fwrite(fmt,...)
   return io.write(string.format(fmt,unpack(arg)))

end?


  这个例子将文本格式化操作和写操作组合为一个函数。


       
       

命名参数?

Lua 的函数参数是和位置相关的,调用时实参会按顺序依次传给形参。有时候用名字指定参数是很有用的,比如 rename 函数用来给一个文件重命名,有时候我们我们记不清命名前后两个参数的顺序了:?

-- invalid code
rename(old="temp.lua",new="temp1.lua")

上面这段代码是无效的,Lua 可以通过将所有的参数放在一个表中,把表作为函数的唯一参数来实现上面这段伪代码的功能。因为 Lua 语法支持函数调用时实参可以是表的构造。?

根据这个想法我们重定义了 rename:?

function rename (arg)
   return os.rename(arg.old,arg.new)

end?



       
       

lua函数?

Lua 中的函数是带有词法定界(lexical scoping)的第一类值(first-class values)。

第一类值指:在 Lua 中函数和其他值(数值、字符串)一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。

词法定界指:被嵌套的函数可以访问他外部函数中的变量。这一特性给 Lua 提供了强大的编程能力。?

闭包?

当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部
变量,这种特征我们称作词法定界。虽然这看起来很清楚,事实并非如此,词法定界加
上第一类函数在编程语言里是一个功能强大的概念,很少语言提供这种支持。

下面看一个简单的例子,假定有一个学生姓名的列表和一个学生名和成绩对应的表;现在想根据学生的成绩从高到低对学生进行排序,可以这样做:

names = {"Peter","Paul",0)">"Mary"}
grades = {Mary = 10,Paul = 7,Peter = 8}
table.sort(names,function (n1,n2)

return grades[n1] > grades[n2] -- compare the grades

end)


  假定创建一个函数实现此功能: 
function sortbygrade (names,grades)
   table.sort(names,n2)

return grades[n1] > grades[n2] -- compare the gradesend)

end?


例子中包含在 sortbygrade 函数内部的 sort 中的匿名函数可以访问 sortbygrade 的参数grades,在匿名函数内部 grades 不是全局变量也不是局部变量,我们称作外部的局部变量(external local variable)或者 upvalue。(upvalue 意思有些误导,然而在 Lua 中他的存在有历史的根源,还有他比起 external local variable 简短)。

看下面的代码:

            
            
function newCounter()
    local i = 0

return function()

i=i+1

return i

end

end

c1 = newCounter()

print(c1()) --> 1

print(c1()) --> 2?

正确的尾调用(Proper Tail Calls)

尾调用是一种类似在函数结尾的 goto 调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。?

function f(x) return g(x)

end?

g 的调用是尾调用。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读