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

Lua学习之function

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

第五章 Lua学习笔记之函数

?

函数有两个用途

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

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

function unpack(t,i)

?

i = i or 1

?

if t[i] then

?

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

end

?

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}

g(3,4,5,6) a = 3,arg = {5,6,n = 2}

?

如果只想要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)

end

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

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

w = Window {

?

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

title? = "lua",background = "blue",

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")

?

end

?

?

_Window(options.title,

?

options.x or 0,

options.y or 0,

options.width,options.height,

options.background or "white",

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

?

end

?

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)

?

end

?

闭包

?

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

?

function newCounter()

?

???? local i = 0

?

???? return function ()

?

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

?

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

?

???? end

?

end

?

?

?

ca = newCounter()

?

cb = newCounter()

?

print(ca())

?

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

?

???? end

?

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,

?

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

?

}

?

--3.Lua提供另一种语法方式

?

Lib = {}

?

function Lib.foo (x,y)

?

?

???? return x + y

?

end

?

function Lib.go0 (x,y)

?

???? return x - y

?

end

?

?

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

Local f = function(…)

End

?

Local function f (…)

….

end

?

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

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

?face = function(n)

?

?? If(n==1)

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

Else

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

End

End

?

?

尾调用:

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

?

Function f(x)

???????????

Return g(x)

?

End

--g(x)即为尾调用

?

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

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

?

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

?

Function foo(n)

?

If(n>0)then

Return foo(n-1)

End

?

End

?

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

例如:

?

Function f(x)

?

G(x)

?

R

return

end

--不是尾调用

?

?

下面的例子也不是尾调用

Return g(x)+1

?

Return(g(x))

?

Return x or g(x)

?

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

?

?

?

?

[sql] view plain copy print ?
  1. local?function?languageTest()???
  2. ????--?table?test ??
  3. ????local?names?=?{"Peter",?"Paul",?"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. ????????????????return?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. ????local?function?values(t)??
  32. ????????local?i?=?0;??
  33. ????????return?function()?i=i+1;?return?t[i]?end??
  34. ????end??
  35. ????for?elm?in?values(names)?do??
  36. ????????print(elm)??
  37. ????end??
  38. ??????
  39. --??--?for?test2 ??
  40. --??for?k?in?pairs(names)?do ??
  41. --??????print(k) ??
  42. --??end ??
  43. end??
  44. ??
  45. local?function?tableTest()???
  46. ????local?Set?=?{}??
  47. ????local?mt?=?{}??
  48. ??????
  49. ????--?create?a?new?set?with?teh?values?of?the?given?list ??
  50. ????Set.new?=?function(l)??
  51. ????????local?set?=?{}??
  52. ????????setmetatable(set,?mt)??
  53. ????????for?_,?v?in?ipairs(l)?do?set[v]?=?true?end??
  54. ????????return?set;??
  55. ????end??
  56. ??????
  57. ????Set.union?=?function(a,?b)??
  58. ????????if?getmetatable(a)?~=?mt?or?getmetatable(b)?~=?mt?then??
  59. ????????????error("attempt?to?'add'?a?set?with?a?non-set?value",?2);??
  60. ????????end??
  61. ????????local?res?=?Set.new?{}??
  62. ????????for?k?in?pairs(a)?do?res[k]?=?true?end??
  63. ????????for?k?in?pairs(b)?do?res[k]?=?true?end??
  64. ????????return?res??
  65. ????end??
  66. ??????
  67. ????Set.intersection?=?function(a,?b)??
  68. ????????local?res?=?Set.new?{}??
  69. ????????for?k?in?pairs(a)?do???
  70. ????????????res[k]?=?b[k]??
  71. ????????end??
  72. ????????return?res??
  73. ????end??
  74. ??????
  75. ????Set.tostring?=?function(set)??
  76. ????????local?l?=?{}??
  77. ????????for?e?in?pairs(set)?do???
  78. ????????????l[#l+1]?=?e??
  79. ????????end??
  80. ????????return?"{"?..?table.concat(l,?",?")?..?"}"??
  81. ????end??
  82. ??????
  83. ????Set.print?=?function(s)??
  84. ????????print(Set.tostring(s))??
  85. ????end??
  86. ??????
  87. ????mt.__add?=?Set.union??
  88. ????mt.__mul?=?Set.intersection??
  89. ????mt.__tostring?=?Set.tostring??
  90. ????mt.__le?=?function(a,?b)??
  91. ????????for?k?in?pairs(a)?do???
  92. ????????????if?not?b[k]?then?return?false?end??
  93. ????????end??
  94. ????????return?true??
  95. ????end??
  96. ????mt.__lt?=?function(a,?b)??
  97. ????????return?a<=b?and?not?(b<=a)??
  98. ????end??
  99. ????mt.__eq?=?function(a,?b)??
  100. ????????return?a<=b?and?b<=a??
  101. ????end??
  102. ??????
  103. ??????
  104. ????local?s1?=?Set.new?{10,?20,?30,?50}??
  105. ????local?s2?=?Set.new?{30,?1}??
  106. ????local?s3?=?s1+s2+s2??
  107. --??local?s3?=?s1+s2+s2?+?8 ??
  108. ????Set.print(s3)??
  109. ????Set.print((s1+s2)*s1)??
  110. ??????
  111. ????s1?=?Set.new{2,?4}??
  112. ????s2?=?Set.new{4,?10,?2}??
  113. ????print(s1<=s2)??
  114. ????print(s1<s2)??
  115. ????print(s1>=s2)??
  116. ????print(s1>s2)??
  117. ????print(s1==s2*s1)??
  118. ??????
  119. ????s1?=?Set.new?{10,?4,?5}??
  120. ????print(s1)??
  121. ??????
  122. --??mt.__metatable?=?"not?your?business" ??
  123. --??print(getmetatable(s1)) ??
  124. --??setmetatable(s1,?{}) ??
  125. ??????
  126. ????local?Window?=?{}?--?create?a?namespace ??
  127. ????--create?teh?prototype?with?default?values. ??
  128. ????Window.prototype?=?{x=0,?y=0,?width=100,?height=100}??
  129. ????Window.mt?=?{}?--?create?a?metatable ??
  130. ????--declare?the?constructor?function ??
  131. ????function?Window.new(o)??
  132. ????????setmetatable(o,?Window.mt)??
  133. ????????return?o??
  134. ????end??
  135. ????Window.mt.__index?=?function(table,?key)??
  136. ????????return?Window.prototype[key]??
  137. ????end??
  138. --??Window.mt.__index?=?Window.prototype ??
  139. ????w?=?Window.new?{x=10,?y=20}??
  140. ????print(w.x)??
  141. ??????
  142. ??????
  143. ????--?Tables?with?default?values ??
  144. ????local?function?setDefault(t,?d)??
  145. ????????local?mt?=?{__index?=?function()?return?d?end}??
  146. ????????setmetatable(t,?mt)??
  147. ????end??
  148. ????local?tab?=?{x=10,?y=20}??
  149. ????print(tab.x,?tab.z)??
  150. ????setDefault(tab,?0)??
  151. ????print(tab.x,?tab.z)??
  152. ??????
  153. ????local?mt?=?{__index?=?function(t)?return?t.___?end?}??
  154. ????local?function?setDefault(t,?d)??
  155. ????????t.___?=?d??
  156. ????????setmetatable(t,?mt)??
  157. ????end??
  158. ??????
  159. ????--?Tracking?table?accesses ??
  160. ????local?t?=?{}?--?original?table?(created?somewhere) ??
  161. ????--?keep?a?private?access?to?the?original?table ??
  162. ????local?_t?=?t??
  163. ????--?create?proxy ??
  164. ????t?=?{}??
  165. ????--?create?metatable ??
  166. ????local?mt?=?{??
  167. ????????__index?=?function(t,?k)??
  168. ????????????print("*access?to?element?"?..?tostring(k))??
  169. ????????????return?_t[k]??
  170. ????????end,??
  171. ??????????
  172. ????????__newindex?=?function(t,?k,?v)??
  173. ????????????print("*update?of?element?"?..?tostring(k)?..?"?to?"?..?tostring(v))??
  174. ????????????_t[k]?=?v?--?update?original?table ??
  175. ????????end??
  176. ????}??
  177. ????setmetatable(t,?mt)??
  178. ????t[2]?=?"hello"??
  179. ????print(t[2])??
  180. ??????
  181. ????--?Read-only?tables ??
  182. ????function?readOnly(t)??
  183. ????????local?proxy?=?{}??
  184. ????????local?mt?=?{??
  185. ????????????__index?=?t,??
  186. ????????????__newindex?=?function(t,?v)??
  187. ????????????????error("attempt?to?update?a?read-only?table",?2)??
  188. ????????????end??
  189. ????????}??
  190. ????????setmetatable(proxy,?mt)??
  191. ????????return?proxy??
  192. ????end??
  193. ????days?=?readOnly?{"Sunday",?"Monday",?"Tuesday",?"Wednesday",?"Thursday",?"Friday",?"Saturday"}??
  194. ????print(days[1])???
  195. --??days[2]?=?"Noday" ??
  196. end??
  197. ??
  198. local?function?objectTest()??
  199. ????local?Account?=?{??
  200. ????????balance?=?0,??
  201. ????????new?=?function(self,?o)??
  202. ????????????o?=?o?or?{}?--?create?table?is?user?does?not?provide?one ??
  203. ????????????setmetatable(o,?self)??
  204. ????????????self.__index?=?self??
  205. ????????????return?o??
  206. ????????end,??
  207. ????????withdraw?=?function(self,?v)??
  208. ????????????if?v>self.balance?then?error"insufficient?funds"?end??
  209. ????????????self.balance?=?self.balance?-?v??
  210. ????????end,??
  211. ????????deposit?=?function(self,?v)??
  212. ????????????self.balance?=?self.balance?+?v??
  213. ????????end??
  214. ????}??
  215. ??????
  216. ????local?a?=?Account:new?{balance?=?0}??
  217. ????a:deposit(100.00)??
  218. ????print(a.balance)??
  219. ????local?b?=?Account:new()??
  220. ????print(b.balance)??
  221. ????b.balance?=?123??
  222. ????print(b.balance)??
  223. ????b:withdraw(100)??
  224. ????print(b.balance)??
  225. ????print(a.balance)??
  226. ??????
  227. ??????
  228. ????--?inheritance ??
  229. ????local?SpecialAccount?=?Account:new({??
  230. ????????withdraw?=?function(self,?v)??
  231. ????????????if?v?-?self.balance?>=?self:getLimit()?then??
  232. ????????????????error"insufficient?funds"??
  233. ????????????end??
  234. ????????????self.balance?=?self.balance?-?v??
  235. ????????end,???
  236. ????????getLimit?=?function(self)???
  237. ????????????return?self.limit?or?0??
  238. ????????end??
  239. ????})??
  240. ??????
  241. ????local?s?=?SpecialAccount:new?{limit=1000.00}??
  242. ????s:deposit(100.00)??
  243. ????s:withdraw(200.00)??
  244. ????print("s:",?s.balance)??
  245. end??
  246. ??
  247. ??
  248. local?function?main()??
  249. ????languageTest();??
  250. ????tableTest();??
  251. ????objectTest();??
  252. end??
  253. main()??

(编辑:李大同)

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

    推荐文章
      热点阅读