- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Lua中的模块与module函数详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
很快就要开始介绍Lua里的“面向对象”了,在此之前,我们先来了解一下Lua的模块.
1.编写一个简单的模块 。
Lua的模块是什么东西呢?通常我们可以理解为是一个table,这个table里有一些变量、一些函数… 。
等等,这不就是我们所熟悉的类吗?
没错,和类很像(实际上我说不出它们的区别)。 我们来看看一个简单的模块,新建一个文件,命名为game.lua,代码如下:
。
我们定义了一个table,并且给这个table加了两个字段,只不过这两个字段的值是函数而已.
至于如何使用模块,那就要用到我们之前介绍过的require了。 我们在main函数里这么使用:
。
注意,我们要require其他文件的时候,要把文件路径给设置好,否则会找不到文件。 因为我使用的是Cocos Code IDE,直接调用addSearchPath函数就可以了,我的game.lua文件是在src目录下的。 好了,运行代码,结果如下:
OK,这就是一个很简单的模块,如果我们习惯了Java、C++等面向对象语言,那也可以简单地把模块理解为类.
。
2.为以后的自己偷懒——避免修改每个函数中的模块名 。
假设我们想把刚刚的game模块改个名字,改成eatDaddyGame,那么,我们需要做以下两件事情:
1).修改game.lua的文件名 2).修改game.lua的内容,把所有的game改成eatDaddyGame 目前的game.lua函数还算少,就两个,实际上一个模块的函数肯定不会少的,那么,要这么去改这些函数,太烦了.
如果批量修改,又怕有哪个地方改错.
于是,我们可以这么偷懒:
。
我们用一个局部变量M来代替了game,于是,以后我们只需要修改前面两个的game就可以了,函数部分的内容完全不需要去修改.
这个偷懒其实蛮有用的,某些情况下,修改越少,越安全~ 。
3.更进一步的偷懒——模块名参数 。
实际上,我们可以更加得偷懒,以后修改模块名,只需要修改模块的文件名就可以了,文件内容可以不管,具体怎么实现?
看代码:
。
留意一下,这里有一个 local modelName = … “…”就是传递给模块的模块名,在这里其实就是“game”这个字符串。 接着,有点微妙了,还记得之前介绍的全局环境_G吗?我们以”game”作为字段名,添加到_G这个table里.
于是,当我们直接调用game的时候,其实就是在调用_G["game"]的内容了,而这个内容就是这里的M。 能逻辑过来吗?就是这么简单,在你没有忘记_G的前提下~ 。
4.利用非全局环境制作更简洁和安全的模块 。
如果说,刚刚已经达到了我们作为高(ai)智(zhe)商(teng)人群的巅峰,那,你就太天真了.
巅峰就是要拿来超越的,还记得我们的非全局环境吗?就是那个setfenv函数。 我们来看看下面的代码:
。
我们把game.lua这个模块里的全局环境设置为M,于是,我们直接定义函数的时候,不需要再带M前缀.
因为此时的全局环境就是M,不带前缀去定义变量,就是全局变量,这时的全局变量是保存在M里.
所以,实际上,play和quit函数仍然是在M这个table里。 于是,我们连前缀都不用写了,这真是懒到了一个极致,简直就是艺术~ 。
另外,由于当前的全局环境是M,所以, 在这里不需要担心重新定义了已存在的函数名,因为外部的全局变量与这里无关了。 当然,如果大家现在就运行代码,肯定会报错了.
因为我们的全局环境改变了,所以print函数也找不到了.
为了解决这个问题,我们看看第5条内容吧~ 。
5.解决原全局变量的无法找到的问题——方案1 。
第一个方法,就是我们之前介绍过的,使用继承,如下代码:
。
没错,使用__index元方法就能解决这个问题了,当找不到print等函数时,就会去原来的_G里查找.
6.解决原全局变量的无法找到的问题——方案2 。
第二个方法更简单,使用一个局部变量把原来的_G保存起来,如下代码:
。
这种方法的缺点比较明显,那就是,每次调用print等函数时,都要使用_G前缀.
7.解决原全局变量的无法找到的问题——方案3 。
第三个方法比较繁琐,使用局部变量把需要用到的其他模块保存起来,如下代码:
。
这种方法的缺点更明显了,所有用到的模块都要用局部变量声明一次,烦人。 但,就速度而言,第三种方案比第二种方案快,第二种方法又比第一种快。 但至于快多少,我也不知道,只是理论上~我也没测试.
8.你就笑吧,但,我还想更加偷懒——module函数 。
本以为刚刚介绍的那些技巧已经够偷懒的吧? 但Lua似乎知道我们有多懒似的,它竟然把我们把这一切都自动完成了。 再来回忆我们刚刚为了偷懒而写的几句代码:
。
就这几句代码,其实我们可以忽略不写,因为,我们有module函数,它的功能就相当于写了这些代码。 我们修改一下game.lua的内容,如下代码:
。
注意,前面的几行代码都没了,只留下了一个module函数的调用.
module函数的调用已经相当于之前的那些代码了.
而package.seeall参数的作用就是让原来的_G依然生效,相当于调用了:setmetatable(M, {__index = _G}); 再次留意一下,代码末尾的return M也不见了,因为module函数的存在,已经不需要我们主动去返回这个模块的table了.
9.结束 。
这篇结束的内容似乎有点多,我也写了一个多小时了.
其实我还省略不少东西,比如package.loaded,lua路径查找的规则等等.
因为这些Cocos Code IDE,或者说是Cocos2d-x lua,已经帮我们做了,我们不需要去管这些.
所以我就避重就轻了,啊不,是顾此失彼…不对~!反正,就是那个意思了~! 。
最后此篇关于Lua中的模块与module函数详解的文章就讲到这里了,如果你想了解更多关于Lua中的模块与module函数详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
如何从 a.lua 传递值至 b.lua ? 让我们说在我的 a.lua我有这个变量代码。 local value = "Hello WOrld!" director:changeScene ("b"
我有一个使用命令行解释器运行的 lua 脚本,该脚本需要从文件加载表。 该表存储如下: create_object_action = { reflexive = true, which
我通过静态链接的方式在我的项目中嵌入了 Win32 上的 Lua(不,我不能切换到 DLL)。我想捆绑更多使用 native 代码的 Lua 扩展 - 而不仅仅是纯 .lua 文件。具体来说,我想捆绑
我需要一些帮助来解析 lua 文件的命令行。我正在执行一个 lua 文件,该 lua 文件有一个命令“dofile(2nd.lua-file)”,但是,我想通过第一个 lua 文件将一些参数传递给第二
这是我的代码示例: listOfPeople = {} listOfPeople["test"] = "hello" listOfPeople = nil “hello”字符串是否丢失并形成内存泄漏?
在一些源代码中,我看到了“Underscore.lua”模块的用法。 _ = require 'underscore' 描述如下: Underscore.lua is a Lua library th
在一些源代码中,我看到了“Underscore.lua”模块的用法。 _ = require 'underscore' 描述如下: Underscore.lua is a Lua library th
我一直在编程 io.write("How many languages do you speak?\n") answer = io.read() if (answer == 1) then io.wr
这个问题在这里已经有了答案: Getting multiple values from a function without creating a variables in LUA (2 个答案)
在阅读 Lua manual 时我遇到了这部分: 函数调用和赋值都可以以左括号开头。这种可能性导致了 Lua 语法中的歧义。考虑以下片段: a = b + c (print or io.write)(
假设我有以下循环: for name in poll() do if name == "quit" then return 0 end end "quit" 字符串是否
Pandoc 通过其 --lua-filter 参数原生支持 lua 过滤器。 但是,我想知道它使用的是什么版本的 lua,以及是否可以将 lua 模块(我相信它依赖于 C 代码)导入其中。 这是我调
这种语言是面向对象的语言吗? 它经常用作OO语言吗? 最佳答案 Lua 完全有能力 prototype-based类似于 JavaScript 的面向对象编程。 Prototype-based pro
我想从 C++ 传递一个 Lua 脚本(Lua 解释器可以处理的代码)并取回结果。 我在网上查看,但找不到任何可以帮助我的示例。我可以从 C++ 调用 Lua 函数,但这需要您使用 Lua 函数创建一
我正在阅读“在 Lua 中编程”,但我不明白这段代码中 Lua 中函数的行为: function newCounter () local i = 0 return function () --
我最近一直在查找 Lua 中的链表,并有一个简单的问题,到目前为止我还没有找到答案 local head = nil head = {next = head, value = "d"} head =
我知道有tonumber()函数,但是问题是我需要转换较大的数字,例如1000100110100011111010101001001001001100100101。我可以自己写,但是有没有办法将其集成
是否可以在 Lua 中对多个值执行算术运算。 我在 Windows 5.1.4 上使用 Lua。 目前我必须将多个值放入一个表中,然后解压缩它们,我希望能够跳过这一步。 是否可以。 这是我目前拥有的:
有什么区别吗 local splitPathFileExtension = function (res) end 和 function splitPathFileExtension(res) end
在下面的代码中,谁能解释一下 b,a = a,b 内部是如何工作的? -- Variable definition: local a, b -- Initialization a = 10 b = 3
我是一名优秀的程序员,十分优秀!