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

Lua function

发布时间:2020-12-14 22:05:16 所属栏目:大数据 来源:网络整理
导读:第五章 Lua学习笔记之函数 ? 函数有两个用途 1.??????完成指定功能,函数作为调用语句使用 2.??????计算并返回值,函数作为赋值语句的表达式使用 function unpack(t,i) i = i or 1 if t[i] then ?????????? return t[i],unpack(t,i + 1) end ? Lua 中的函数

第五章 Lua学习笔记之函数

?

函数有两个用途

1.??????完成指定功能,函数作为调用语句使用

2.??????计算并返回值,函数作为赋值语句的表达式使用

function unpack(t,i)

i = i or 1

if t[i] then

?????????? return t[i],unpack(t,i + 1)

end

?

Lua 中的函数和 Javascript 中的有些相似,函数在书写的时候,前面都需要加上?function?这个关键字,?上篇文章中提过?function?这个关键字,他在 Lua 中也是一种类型。下面我们来看看 Lua 中的一个简单函数是怎么写的。

?

 
 
  1. function?printHello(a,b)??--a,b为参数?
  2. print(a,b);?
  3. print("Hello")?
  4. end?

? ??在上面的一段函数中,函数的开头需要function?关键字来修饰它,表明它是一个“函数类型” ,当然既然成为“类型” 我们在程序中也可以这样写:

  1. testFuction=function?(a,b)?return?a+b?end??
  2. --testFuction就相当于这个函数的函数名了?

? ??所以说,Lua 的函数是很灵活的。

? ? 在C/C++中我们总是用"{ }" 来括起一个函数,但是Lua中有所不同,大家也注意到了上边的代码,最后跟随着一个 "end" ,这个 end 就是来表明一个函数的结尾的。好了对于Lua中函数的初步认识就到这里,更深入的我们要留在以后实践中来体会。

?

?

lua函数接受可变参数,lua讲函数的参数放在一个叫arg的表中,除了参数之外,表中还有一个域n表示参数个数

function g(a,b,…)end

g(3)? a = 3,b = nil,arg = {n = 0}

g(3,4) a = 3,b = 4,arg = {n=0}

如果只想要string.find返回的第二个值:

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

s = "12345678"

p = "3456"

local _,x = string.find(s,p)

print(x)

命名参数

Lua的函数参数和位置相互关联,调用时实参安顺序依次传给形参。

有时候用名字指定参数是很有用的。

比如用rename函数给一个文件重新命名,有时候我们记不得命名前后两个参数的顺序了

Function rename(arg)

Return os.rename(arg.old,arg.new)

?Rename{old = “temp.lua”,new=”temp1.lua”}

当函数参数很多时,这样处理就比较方便,简单。例如窗口创建函数;

w = Window {

x = 0,y = 0,width = 300,height = 200,

title? = "lua",background = "blue",43); font-family:Arial; font-size:14px; line-height:26px"> border = true

}

function Window(options)

if type(options.title) ~= "string" then

error("no title")

elseif type(options.width) ~= "number" then

error("no width")

elseif type(options.height) ~= "number" then

error("no height")

_Window(options.title,43); font-family:Arial; font-size:14px; line-height:26px"> options.x or 0,43); font-family:Arial; font-size:14px; line-height:26px"> options.y or 0,43); font-family:Arial; font-size:14px; line-height:26px"> options.width,options.height,43); font-family:Arial; font-size:14px; line-height:26px"> options.background or "white",43); font-family:Arial; font-size:14px; line-height:26px"> options.border

)

End

第六章再论函数

Lua中的函数有以下两个特点:

1.??????lua中的函数和其他变量(string,number) 一样,可以赋值,可以放在变量中,可以放在表中。可以作为函数参数,可以作为函数返回值。

2.??????被嵌套的内部函数可以访问他外面的数据成员

3.??????Lua函数可以是匿名的,当我们提到函数名(比如print),其实是print这个变量指向打印输出这个函数,当然,打印输出函数也可以由其他变量指向。例如:

a = { p = print}

a.p("hello world")

print = math.sin

a.p(print(1))

sin = a.p

sin(10,20)

没错,函数就是变量,就是值。

function foo(x)

????

???? return 2*x

foo = function (x)

?? return 2*x end

函数定义就是把function这个值赋值给foo这个变量。

我们使用function(x)…end 创建函数和 {}创建表是一个道理。

Table标准库有一个排序函数,接受一个表作为参数对标中的元素进行排序。

这个函数必须对不同类型的元素进行升降排序,Lua不是尽可能多的传入参数解决这种问题,而是接受一个排序函数作为参数,(类似c++的函数指针)排序函数作为输入参数,并且返回两个参数比较后的大小关系(用c++可以实现这个万能的排序算法)

例如:

name = { "peter","paul","mary"}

grades = { mary = 10,paul = 7,peter = 13 }

table.sort(name,function (n1,n2) return grades[n1] > grades[n2] end )

在lua中,其他函数作为函数的参数,成这个函数为高级函数,没有什么特殊的地方。

function sortbygrade (name,grades)

???? table.sort(name,n2) return grades[n1] > grades[n2] end)

闭包

包含在sortbygrade中的sort的参数匿名function 可以访问sortbygrade的grades在匿名function 内部grades既不是全局变量,也不是局部变量。他别称为外部的局部变量或upvalue

function newCounter()

???? local i = 0

???? return function ()

?????????????? i = i + 1

?????????????? return i

???? end

ca = newCounter()

cb = newCounter()

print(ca())

print(cb())

匿名函数使用upvalue i保存他的计数

当我们调用匿名函数的时候I已经超出了他的适用范围,因为创建i的函数newCounter已经返回了。简单滴说闭包是一个函数加上他可以正确访问的upvalues,如果我们再次调用newCOunter,将创建一个新的局部变量i

因此我们得到了一个作用在新建的i上的新闭包。

技术上讲,闭包是值而不是函数。函数仅仅是闭包的一个原形声明;我们继续使用术语函数代替闭包。

闭包的功能:

作为高级函数的参数。

作为函数嵌套的函数。

作为回调函数。

创建沙箱。

do

???? local oldOpen = io.open

???? io.open = function (filename,mode)

?????????????? if access_OK(filename,mode) then

??????????????????????? return oldOpen(filename.mode)

?????????????? else

??????????????????????? return nil,"access denied"

?????????????? end

非全局函数

Lua中函数分为全局和非全局

大部分作为table的域(math.sin io.read)

--1.表和函数在一起

Lib = {}

Lib.foo = function (x,y) return x + y end

Lib.goo = function (x,y) return x - y end

--2.使用表构造函数

Lib = {

foo = function (x,y) return x + y end,43); font-family:Arial; font-size:14px; line-height:26px"> goo = function (x,43); font-family:Arial; font-size:14px; line-height:26px"> --3.Lua提供另一种语法方式

function Lib.foo (x,y)

???? return x + y

function Lib.go0 (x,43); font-family:Arial; font-size:14px; line-height:26px"> ???? return x - y

当我们把函数赋值给局部变量时,函数成了局部的,就是说局部函数像局部变量一样在一定范围内有效。声明局部函数的方式:

Local f = function(…)

Local function f (…)

….

需要注意声明递归局部函数

Local face—声明和定义必须分开

?face = function(n)

?? If(n==1)

??????????? Return 1

Else

??????????? Return n*face(n-1)

尾调用:

如果函数最后一句执行的是函数调用,我们称这种调用为尾调用

Function f(x)

???????????

Return g(x)

--g(x)即为尾调用

例子中f调用g之后不会做任何事情

这时候,g不需要返回到f,所以尾调用之后,栈不保存f的任何信息。

由于尾调用不需要栈空间,所以尾调用递归可以无限次进行

Function foo(n)

If(n>0)then

Return foo(n-1)

需要注意:为调用之后确实不做什么事,不做什么事的调用不一定是尾巴调用

G(x)

R

return

--不是尾调用

下面的例子也不是尾调用

Return g(x)+1

Return(g(x))

Return x or g(x)

以上表达式的最后一步计算的不是g(x)本身,所以不是尾函数

?

  1. local?function?languageTest()???
  2. ????--?table?test???
  3. ????local?names?=?{"Peter",?"Paul",54); background-color:inherit">"Mary"}??
  4. ????local?grades?=?{Mary=10,?Paul=7,?Peter=8}??
  5. ????table.sort(names,?function(n1,?n2)???
  6. ????????return?grades[n1]?>?grades[n2]??
  7. ????end)??
  8. for?i=1,?#names?do??
  9. ????????print(names[i])??
  10. end??
  11. ??????
  12. --?function?test???
  13. ????local?function?newCounter(name)??
  14. local?i?=?0??
  15. ????????return?function()??
  16. ????????????????i?=?i+1??
  17. ????????????????name?..?":"?..?i??
  18. ????????????end??
  19. ????end??
  20. ??????
  21. ????local?c1?=?newCounter("c1")??
  22. local?c2?=?newCounter("c2")??
  23. ??????
  24. ????print(c1())??
  25. ????print(c1())??
  26. ????print(c2())??
  27. ????print(c1())??
  28. ????print(c2())??
  29. ??????
  30. --?for?test???
  31. ????function?values(t)??
  32. local?i?=?0;??
  33. ????????function()?i=i+1;?return?t[i]?for?elm?in?values(names)?do??
  34. ????????print(elm)??
  35. ???? ??????
  36. --??--?for?test2???
  37. --??for?k?in?pairs(names)?do???
  38. --??????print(k)???
  39. --??end???
  40. ??
  41. function?tableTest()???
  42. Set?=?{}??
  43. ????local?mt?=?{}??
  44. ??????
  45. ????--?create?a?new?set?with?teh?values?of?the?given?list???
  46. Set.new?=?function(l)??
  47. ????????set?=?{}??
  48. ????????setmetatable(set,?mt)??
  49. ????????for?_,?v?in?ipairs(l)?do?set[v]?=?true?set;??
  50. ????Set.union?=?function(a,?b)??
  51. ????????if?getmetatable(a)?~=?mt?or?getmetatable(b)?~=?mt?then??
  52. ????????????error("attempt?to?'add'?a?set?with?a?non-set?value",?2);??
  53. end??
  54. ????????local?res?=?Set.new?{}??
  55. for?k?in?pairs(a)?do?res[k]?=?in?pairs(b)?do?res[k]?=?return?res??
  56. ????Set.intersection?=?Set.new?{}??
  57. ????????in?pairs(a)?do???
  58. ????????????res[k]?=?b[k]??
  59. ????????Set.tostring?=?function(set)??
  60. local?l?=?{}??
  61. ????????for?e?in?pairs(set)?do???
  62. ????????????l[#l+1]?=?e??
  63. ????????return?"{"?..?table.concat(l,54); background-color:inherit">",?")?..?"}"??
  64. ????Set.print?=?function(s)??
  65. ????????print(Set.tostring(s))??
  66. ???? ??????
  67. ????mt.__add?=?union??
  68. ????mt.__mul?=?Set.intersection??
  69. ????mt.__tostring?=?Set.tostring??
  70. ????mt.__le?=? ???????? ????????????if?not?b[k]?then?false?true??
  71. ???? ????mt.__lt?=?return?a<=b?and?not?(b<=a)??
  72. end??
  73. ????mt.__eq?=?and?b<=a??
  74. ???? ??????
  75. ??????
  76. local?s1?=?Set.new?{10,?20,?30,?50}??
  77. ????local?s2?=?Set.new?{30,?1}??
  78. local?s3?=?s1+s2+s2??
  79. --??local?s3?=?s1+s2+s2?+?8???
  80. Set.print(s3)??
  81. ????Set.print((s1+s2)*s1)??
  82. ??????
  83. ????s1?=?Set.new{2,?4}??
  84. ????s2?=?Set.new{4,?10,?2}??
  85. ????print(s1<=s2)??
  86. ????print(s1<s2)??
  87. ????print(s1>=s2)??
  88. ????print(s1>s2)??
  89. ????print(s1==s2*s1)??
  90. ????print(s1)??
  91. ??????
  92. --??mt.__metatable?=?"not?your?business"???
  93. --??print(getmetatable(s1))???
  94. --??setmetatable(s1,?{})???
  95. ??????
  96. local?Window?=?{}?--?create?a?namespace???
  97. ????--create?teh?prototype?with?default?values.???
  98. ????Window.prototype?=?{x=0,?y=0,?width=100,?height=100}??
  99. ????Window.mt?=?{}?--?create?a?metatable???
  100. --declare?the?constructor?function???
  101. ????function?Window.new(o)??
  102. ????????setmetatable(o,?Window.mt)??
  103. ????????return?o??
  104. end??
  105. ????Window.mt.__index?=?table,255); font-weight:bold; background-color:inherit">key)??
  106. return?Window.prototype[key]??
  107. ????--??Window.mt.__index?=?Window.prototype???
  108. ????w?=?Window.new?{x=10,?y=20}??
  109. ????print(w.x)??
  110. ??????
  111. --?Tables?with?default?values???
  112. function?setDefault(t,?d)??
  113. ????????local?mt?=?{__index?=?function()?return?d?end}??
  114. ????????setmetatable(t,?mt)??
  115. ????local?tab?=?{x=10,?y=20}??
  116. ????print(tab.x,?tab.z)??
  117. ????setDefault(tab,?0)??
  118. ????print(tab.x,255); font-weight:bold; background-color:inherit">function(t)?return?t.___?end?}??
  119. ????????t.___?=?d??
  120. --?Tracking?table?accesses???
  121. local?t?=?{}?--?original?table?(created?somewhere)???
  122. ????--?keep?a?private?access?to?the?original?table???
  123. local?_t?=?t??
  124. ????--?create?proxy???
  125. ????t?=?{}??
  126. ????--?create?metatable???
  127. local?mt?=?{??
  128. ????????__index?=?function(t,?k)??
  129. ????????????print("*access?to?element?"?..?tostring(k))??
  130. ????????????return?_t[k]??
  131. end,??
  132. ??????????
  133. ????????__newindex?=? ????????????print("*update?of?element?"?..?tostring(k)?..?"?to?"?..?tostring(v))??
  134. ????????????_t[k]?=?v?--?update?original?table???
  135. ???????? ????}??
  136. ????setmetatable(t,?mt)??
  137. ????t[2]?=?"hello"??
  138. ????print(t[2])??
  139. --?Read-only?tables???
  140. function?readOnly(t)??
  141. ????????local?proxy?=?{}??
  142. local?mt?=?{??
  143. ????????????__index?=?t,??
  144. ????????????__newindex?=? ????????????????error("attempt?to?update?a?read-only?table",?2)??
  145. end??
  146. ????????}??
  147. ????????setmetatable(proxy,255); font-weight:bold; background-color:inherit">return?proxy??
  148. end??
  149. ????days?=?readOnly?{"Sunday",54); background-color:inherit">"Monday",54); background-color:inherit">"Tuesday",54); background-color:inherit">"Wednesday",54); background-color:inherit">"Thursday",54); background-color:inherit">"Friday",54); background-color:inherit">"Saturday"}??
  150. ????print(days[1])???
  151. --??days[2]?=?"Noday"???
  152. end??
  153. ??
  154. function?objectTest()??
  155. ????local?Account?=?{??
  156. ????????balance?=?0,??
  157. ????????new?=?function(self,?o)??
  158. ????????????o?=?o?or?{}?--?create?table?is?user?does?not?provide?one???
  159. ????????????setmetatable(o,?self)??
  160. ????????????self.__index?=?self??
  161. ???????????? ????????withdraw?=? ????????????if?v>self.balance?then?error"insufficient?funds"?end??
  162. ????????????self.balance?=?self.balance?-?v??
  163. ????????deposit?=? ????????????self.balance?=?self.balance?+?v??
  164. ???????? ????}??
  165. ??????
  166. local?a?=?Account:new?{balance?=?0}??
  167. ????a:deposit(100.00)??
  168. ????print(a.balance)??
  169. ????local?b?=?Account:new()??
  170. ????print(b.balance)??
  171. ????b.balance?=?123??
  172. ????print(b.balance)??
  173. ????b:withdraw(100)??
  174. ????print(b.balance)??
  175. ????print(a.balance)??
  176. --?inheritance???
  177. ????local?SpecialAccount?=?Account:new({??
  178. ????????withdraw?=? ????????????if?v?-?self.balance?>=?self:getLimit()?then??
  179. ????????????????error"insufficient?funds"??
  180. ???????????? ????????????self.balance?=?self.balance?-?v??
  181. ???????? ????????getLimit?=?function(self)???
  182. ????????????return?self.limit?or?0??
  183. end??
  184. ????})??
  185. local?s?=?SpecialAccount:new?{limit=1000.00}??
  186. ????s:deposit(100.00)??
  187. ????s:withdraw(200.00)??
  188. ????print("s:",?s.balance)??
  189. ??
  190. ??
  191. function?main()??
  192. ????languageTest();??
  193. ????tableTest();??
  194. ????objectTest();??
  195. end??
  196. main()??
    ????--?table?test??
  1. ????local?names?=?{"Peter",54); background-color:inherit">"Paul",54); background-color:inherit">"Mary"}??
  2. ????local?grades?=?{Mary=10,?Peter=8}??
  3. ????table.sort(names,255); font-weight:bold; background-color:inherit">function(n1,?n2)???
  4. ????????return?grades[n1]?>?grades[n2]??
  5. ????end)??
  6. for?i=1,?#names?do??
  7. ????????print(names[i])??
  8. end??
  9. ??????
  10. --?function?test??
  11. ????function?newCounter(name)??
  12. local?i?=?0??
  13. ????????return?function()??
  14. ????????????????i?=?i+1??
  15. ????????????????name?..?":"?..?i??
  16. ????????????end??
  17. ????end??
  18. ??????
  19. ????local?c1?=?newCounter("c1")??
  20. local?c2?=?newCounter("c2")??
  21. ??????
  22. --?for?test??
  23. ????function?values(t)??
  24. local?i?=?0;??
  25. ????????function()?i=i+1;?return?t[i]?for?elm?in?values(names)?do??
  26. ????????print(elm)??
  27. ???? ??????
  28. --??--?for?test2??
  29. --??for?k?in?pairs(names)?do??
  30. --??????print(k)??
  31. --??end??
  32. ??
  33. function?tableTest()???
  34. Set?=?{}??
  35. ????local?mt?=?{}??
  36. ??????
  37. ????--?create?a?new?set?with?teh?values?of?the?given?list??
  38. Set.new?=?function(l)??
  39. ????????set?=?{}??
  40. ????????setmetatable(set,?mt)??
  41. ????????for?_,153); background-color:inherit">in?ipairs(l)?do?set[v]?=?true?set;??
  42. ????Set.union?=?function(a,?b)??
  43. ????????if?getmetatable(a)?~=?mt?or?getmetatable(b)?~=?mt?then??
  44. ????????????error("attempt?to?'add'?a?set?with?a?non-set?value",?2);??
  45. end??
  46. ????????local?res?=?Set.new?{}??
  47. for?k?in?pairs(a)?do?res[k]?=?in?pairs(b)?do?res[k]?=?return?res??
  48. ????Set.intersection?=?Set.new?{}??
  49. ????????in?pairs(a)?do???
  50. ????????????res[k]?=?b[k]??
  51. ????????Set.tostring?=?function(set)??
  52. local?l?=?{}??
  53. ????????for?e?in?pairs(set)?do???
  54. ????????????l[#l+1]?=?e??
  55. ????????return?"{"?..?table.concat(l,?")?..?"}"??
  56. ????Set.print?=?function(s)??
  57. ????????print(Set.tostring(s))??
  58. ???? ??????
  59. ????mt.__add?=?union??
  60. ????mt.__mul?=?Set.intersection??
  61. ????mt.__tostring?=?Set.tostring??
  62. ????mt.__le?=? ???????? ????????????if?not?b[k]?then?false?true??
  63. ???? ????mt.__lt?=?return?a<=b?and?not?(b<=a)??
  64. end??
  65. ????mt.__eq?=?and?b<=a??
  66. ????local?s1?=?Set.new?{10,?50}??
  67. ????local?s2?=?Set.new?{30,?1}??
  68. local?s3?=?s1+s2+s2??
  69. --??local?s3?=?s1+s2+s2?+?8??
  70. Set.print(s3)??
  71. ????Set.print((s1+s2)*s1)??
  72. ??????
  73. ????s1?=?Set.new{2,?4}??
  74. ????s2?=?Set.new{4,?2}??
  75. ????print(s1<=s2)??
  76. --??mt.__metatable?=?"not?your?business"??
  77. --??print(getmetatable(s1))??
  78. ??
  79. ??????
  80. local?Window?=?{}?--?create?a?namespace??
  81. ????--create?teh?prototype?with?default?values.??
  82. ????Window.mt?=?{}?--?create?a?metatable??
  83. --declare?the?constructor?function??
  84. ????function?Window.new(o)??
  85. ????????return?o??
  86. end??
  87. ????Window.mt.__index?=?table,255); font-weight:bold; background-color:inherit">key)??
  88. return?Window.prototype[key]??
  89. ????--??Window.mt.__index?=?Window.prototype??
  90. ????w?=?Window.new?{x=10,119); background-color:inherit">--?Tables?with?default?values??
  91. function?setDefault(t,?d)??
  92. ????????local?mt?=?{__index?=?function()?return?d?end}??
  93. ????local?tab?=?{x=10,?y=20}??
  94. ????print(tab.x,255); font-weight:bold; background-color:inherit">function(t)?return?t.___?end?}??
  95. ????????t.___?=?d??
  96. --?Tracking?table?accesses??
  97. local?t?=?{}?--?original?table?(created?somewhere)??
  98. ????--?keep?a?private?access?to?the?original?table??
  99. local?_t?=?t??
  100. ????--?create?proxy??
  101. ????t?=?{}??
  102. ????--?create?metatable??
  103. local?mt?=?{??
  104. ????????__index?=?function(t,?k)??
  105. ????????????print("*access?to?element?"?..?tostring(k))??
  106. ????????????return?_t[k]??
  107. end,??
  108. ??????????
  109. ????????__newindex?=? ????????????print("*update?of?element?"?..?tostring(k)?..?"?to?"?..?tostring(v))??
  110. ????????????_t[k]?=?v?--?update?original?table??
  111. ???????? ????t[2]?=?"hello"??
  112. ????print(t[2])??
  113. --?Read-only?tables??
  114. function?readOnly(t)??
  115. ????????local?proxy?=?{}??
  116. local?mt?=?{??
  117. ????????????__index?=?t,248)"> ????????????__newindex?=? ????????????????error("attempt?to?update?a?read-only?table",?2)??
  118. end??
  119. ????????}??
  120. ????????return?proxy??
  121. end??
  122. ????days?=?readOnly?{"Sunday",54); background-color:inherit">"Monday",54); background-color:inherit">"Tuesday",54); background-color:inherit">"Wednesday",54); background-color:inherit">"Thursday",54); background-color:inherit">"Friday",54); background-color:inherit">"Saturday"}??
  123. ????print(days[1])???
  124. --??days[2]?=?"Noday"??
  125. end??
  126. ??
  127. function?objectTest()??
  128. ????local?Account?=?{??
  129. ????????new?=?function(self,?o)??
  130. ????????????o?=?o?or?{}?--?create?table?is?user?does?not?provide?one??
  131. ????????????setmetatable(o,248)"> ????????????self.__index?=?self??
  132. ???????????? ????????withdraw?=? ????????????if?v>self.balance?then?error"insufficient?funds"?end??
  133. ????????????self.balance?=?self.balance?-?v??
  134. ????????deposit?=? ????????????self.balance?=?self.balance?+?v??
  135. ????????local?a?=?Account:new?{balance?=?0}??
  136. ????a:deposit(100.00)??
  137. ????print(a.balance)??
  138. ????local?b?=?Account:new()??
  139. --?inheritance??
  140. ????local?SpecialAccount?=?Account:new({??
  141. ????????withdraw?=? ????????????if?v?-?self.balance?>=?self:getLimit()?then??
  142. ????????????????error"insufficient?funds"??
  143. ???????????? ????????????self.balance?=?self.balance?-?v??
  144. ???????? ????????getLimit?=?function(self)???
  145. ????????????return?self.limit?or?0??
  146. end??
  147. ????})??
  148. local?s?=?SpecialAccount:new?{limit=1000.00}??
  149. ????print("s:",?s.balance)??
  150. function?main()??
  151. ????languageTest();??
  152. end??
  153. main()??

(编辑:李大同)

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

    推荐文章
      热点阅读