|
楼主 |
发表于 2020-4-10 23:36:29
|
显示全部楼层
本帖最后由 ecloud 于 2020-4-11 04:24 PM 编辑
四、注意变量的作用域
在Mudlet中开发程序,整个程序被分割成脚本、别名、触发器等部分,分散在系统中
如果你还继续传统的整体化编程思维,就会混乱,尤其是变量的作用域
举例如下:这个例子的意思是,我设置了pfmA,B,C等几个全局对象,同时它们又可以存在于pfmCDGroup这个集合里。那么似乎看上去我穷举出A,B,C跟我遍历pfmCDGroup是一样的结果?- --创建发射和命中触发器
- local function createtr()
- pfmA.firetr = tempTrigger(pfmA.firemsg, [[pfmA:fired()]], 1)
- pfmA.misstr = tempTrigger(pfmA.missmsg, [[pfmA:missed()]], 1)
- pfmB.firetr = tempTrigger(pfmB.firemsg, [[pfmB:fired()]], 1)
- pfmB.misstr = tempTrigger(pfmB.missmsg, [[pfmB:missed()]], 1)
- pfmC.firetr = tempTrigger(pfmC.firemsg, [[pfmC:fired()]], 1)
- pfmC.misstr = tempTrigger(pfmC.missmsg, [[pfmC:missed()]], 1)
- end
- --给共同CD的技能创建触发器
- local function createCDtr()
- for k, p in ipairs(pfmCDGroup) do
- battle.shareCDtr[k] = tempTrigger(p.firemsg, [[battle.groupCD()]])
- end
- end
- function battle.autopfm()
- createtr()
- if #pfmCDGroup > 1 then
- createCDtr()
- end
- if battle.mode == "AAA" then AAA()
- elseif battle.mode == "Loop" then Loop()
- elseif battle.mode == "Bubble" then Bubble()
- elseif battle.mode == "NA" then return
- else
- display("Battle模式设置错误!")
- end
- end
- function battle.groupCD()
- for k, p in ipairs(pfmCDGroup) do
- p:CD()
- end
- end
复制代码 在这段代码中createtr()这个函数写的不够优雅,似乎看上去应该写成createCDtr()里面的for循环模式
那么我为什么使用看上去愚蠢的挨个穷举的方式呢?
因为这里面涉及到了tempTrigger()这个系统级函数,该函数是被Mudlet引擎执行的,因此它所能够接受的必须是全局变量,比如pfmA, B ,C 这些都是全局变量,名称固定。
而for循环里的p是个局部变量。在我这个例子里,p.firemsg 由于直接得到一个静态字符串,是可以作为参数传进去的,而 p:CD() 这种对象方法就无法成为tempTrigger()的参数,因为系统层面不知道p这个对象的存在。你可以在一个循环里直接执行 p:CD() , 就像我后面那个函数里所使用的那样。但是你不能把它作为一个参数传给tempTrigger()
这一点是Mudlet编程非常需要注意的地方。所有以“系统注册”形式存在的函数,比如tempTrigger, tempTimer等,都只能接受静态的全局变量,不能传句柄和对象(除非你深拷贝)
因此,不要介怀使用全局变量,此“全局”非彼“全局”,这里的全局就是给这些系统级函数用的,不要在乎什么优雅不优雅,Mudlet编程需要转换思维 |
|