[Lua基础]包package

包是一种组织代码的方式。很多语言专门提供了某种机制组织全局变量的命名,比如Modula的modules,Java和Perl的packages,C++的namespaces。每一种机制对在package中声明的元素的可见性以及其他一些细节的使用都有不同的规则。但是他们都提供了一种避免不同库中命名冲突的问题的机制每一个程序库创建自己的命名空间,在这个命名空间中定义的名字和其他命名空间中定义的名字互不干涉。

Lua并没有提供明确的机制来实现packages。然而,我们通过语言提供的基本的机制很容易实现他。主要的思想是:像标准库一样,使用表来描述package

使用表实现packages的明显的好处是:我们可以像其他表一样使用packages,并且可以使用语言提供的所有的功能,带来很多便利。大多数语言中,packages不是第一类值(first-class values)(也就是说,他们不能存储在变量里,不能作为函数参数。。。)因此,这些语言需要特殊的方法和技巧才能实现类似的功能。Lua中,虽然我们一直都用表来实现pachages,但也有其他不同的方法可以实现package.

vector3d = {}  -- 包名
function vector3d.function1()
......
end
function vector3d.function2()
......
      if (vector3d.function1()) then
      ......
      end
end
return vector3d 

这样定义的就是一个vector3d包,使用require语言打开这个包后,就可以使用 vector3d.function1和vector3d.function2这两个函数了。

这是最直接最好理解的一种Package定义方式,但是有一定的弊端。这个弊端主要体现在Package的实现过程中。可以看到,即使在

vector3d.function2()中使用function1()函数,也必须完整的加上vector3d包名,否则无法进行函数调用。Package的作者要稍微累一点,不过使用者倒是还好。特别的注意最后的 return vector3d 语句,有了这句后调用者可以按照如下方式重命名包:

MyPackage =  require "vector3d"
MyPackage.function2() 

方式二: 使用局部函数定义所有的Package内函数,然后在Package的结尾处将需要公开的函数直接放入Package。代码看起来像这样:

vector3d = {}  -- 包名
local function function1()
......
end  

local function function2()
......
      if (function1()) then
      ......
      end
end
vector3d = {function1 = functoin1,
function2function2 = function2
}
return vector3d 

最后给包中赋值的部分就是将需要的接口公开的部分。这样做的好处:不需要公开的函数可以完全隐藏起来(都是local函数);Package内部的各个函数相互之间调用的时候不再需要加Package名称进行区分; 可以按照需要随意的重命名Package公开的接口名称。这种方式的弊端在于定义的时候需要写上local,这算不算弊端就看你了 - - 对我个人而言,可以用local
n = {}来保存数据和定义私有变量和函数
。能明确的区分出接口和私有的定义,公开接口的名称还可以随意改变,这就意味着可以随意替换内部实现而不需要影响外部调用者。

无论用什么方法去定义Package,都是为了在逻辑上更好的规划代码层次。LUA中的table机制的确是一个活力无限的机制啊。Package依靠这个实现,LUA本身自己有些机制也依赖于Table(比如全局变量就放在_G表中)

如何"拆开"Package的代码段,很好的展现了table的强大之处(Package也是在table上构筑的逻辑产物)。将Package拆开的意思,就是将所有Package中公开的名字放入_G表中。也就是让 Package.A() 变成_G.A  (_G在一般情况下不需要写,默认引用了)

function openpackage (ns)
      for n,v in pairs(ns)
     do
            _G[n] = v
     end
end 

实现方式

一般在一个Lua文件内以module函数开始定义一个包。module同时定义了一个新的包的函数环境,以使在此包中定义的全局变量都在这个环境中,而非使用包的函数的环境中。理解这一点非常关键。以前面的代码为例, “module(..., package.seeall)”的意思是定义一个包,包的名字与定义包的文件的名字相同(除去文件名后缀,在前面的代码

中,就是“mypack”),并且在包的函数环境里可以访问使用包的函数环境(比如,包的实现使用了print,这个变量没有在包里定义,而是定义在使用包的外部环境中)。

使用方式

一般用require函数来导入一个包,要导入的包必须被置于包路径(packagepath)上。包路径可以通过package.path或者环境变量来设定。一般来说,当前工作路径总是在包路径中。

--testP.lua:
pack = require "mypack" --导入包
print(ver or "No ver defined!")
print(pack.ver)
print(aFunInMyPack or
"No aFunInMyPack defined!")
pack.aFunInMyPack()
print(aFuncFromMyPack or
"No aFuncFromMyPack defined!")
aFuncFromMyPack()

--mypack.lua:
module(..., package.seeall) --定义包
ver = "0.1 alpha"
function aFunInMyPack()
print("Hello!")
end
_G.aFuncFromMyPack =
aFunInMyPack

执行testP.lua的输出结果:
No ver defined!
0.1 alpha
No aFunInMyPack defined!
Hello!
function: 003CBFC0
Hello!
时间: 2024-11-02 23:21:07

[Lua基础]包package的相关文章

JAVA 基础 包(package)

包(package) package的作用 关键字package和import 当编写一个JAVA源码文件时,此文件通常被称为编译单元.每个编译单元都必须有一个后缀名.java. 而在编译单元中可以有一个public类,该类的名称必须和文件的名称相同.文件中允许有其他类,但是不能是public类. 当编译一个.java文件时,文件中的每个类都会有一个后缀为.class的输出文件,文件名和类名相同. Java可运行程序是一组可以打包压缩为一个Java文档文件(JAR,使用Java的jar文档生成器

Lua中的模块(module)和包(package)详解1

这篇文章主要介绍了Lua中的模块(module)和包(package)详解,本文讲解了require函数.写一个模块.package.loaded.module函数等内容,需要的朋友可以参考下 前言 从Lua5.1版本开始,就对模块和包添加了新的支持,可是使用require和module来定义和使用模块和包.require用于使用模块,module用于创建模块.简单的说,一个模块就是一个程序库,可以通过require来加载.然后便得到了一个全局变量,表示一个table.这个table就像是一个命

Lua中的模块(module)和包(package)详解

这篇文章主要介绍了Lua中的模块(module)和包(package)详解,本文讲解了require函数.写一个模块.package.loaded.module函数等内容,需要的朋友可以参考下 前言 从Lua5.1版本开始,就对模块和包添加了新的支持,可是使用require和module来定义和使用模块和包.require用于使用模块,module用于创建模块.简单的说,一个模块就是一个程序库,可以通过require来加载.然后便得到了一个全局变量,表示一个table.这个table就像是一个命

plsql的程序包package

9. 程序包--PACKAGE 9.1 包的定义和编译 包:一个PLSQL相关对象的逻辑分组和单个对象存储在数据库对象中的数据单元.相关的PLSQL对象包括:常量.变量.游标.异常.SP.FUN 包由两部分组成: 规范部分(包头.调用接口)  +  主体部分(包体.实现部分) (1) 包头的创建: create or replace package org_Master is     max_sites_for_an_org number;    type rc is ref cursor;  

Java - 25 Java 包(package)

Java 包(package) 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间. 包的作用 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用. 2 如同文件夹一样,包也采用了树形目录的存储方式.同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别.因此,包可以避免名字冲突. 3 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类. Java使用包(package)这种机制是为了防止命名冲

编写第一个ROS(创建工作空间workspace和功能包package)

刚接触ROS,学着写了第一个程序,怕以后忘记,就将其步骤记录下来.. 首先你必须保证你电脑已安装配置好ROS. 1.创建工作空间(workspace) 我们所创建功能包package,应该全部放到一个叫做工作空间(workspace)的目录中 .你可以把目录存储在你账号的任何位置例如,我所创建的工作空间的是路径/home,同时你可以用任何你喜欢的名字命名你的工作空间,我的工作空间名为 test,现在请使用标准的mkdir命令行去创建一个工作空间.我首先建立一个工作空间,名字为test, 此处创建

去除挖宝报毒的问题,修改基础包的java代码,并且打包

1:去除报毒的  yl-util-countly.jar 2:注释基础包 java 的调用到yl-util-countl的代码 3:充值编译gamebase-lib.jar 1:在项目里执行  ant release 2:生成的bin\classes.jar 就是 gamebase-lib.jar 附件为所以的java代码,只有3个需要改,注释掉了调用yl-util-countl的代码

项目工程的包package与文件夹的关系

项目工程的包package与文件夹的关系: 1. 包名与文件夹是分层关系,包名只是一个字符串而已,包名.对应的是层级的文件夹. 如,com.Immoc.Access包,只是一个字符串.但他对应的windows存储文件夹层级关系则是,src/com/Imooc/Access多个文件夹.

Lua基础 coroutine —— Lua的多线程编程

Lua的coroutine 跟thread 的概念比较相似,但是也不完全相同.一个multi-thread的程序,可以同时有多个thread 在运行,但是一个multi-coroutines的程序,同一时间只能有一个coroutine 在运行,而且当前正在运行的coroutine 只有在被显式地要求挂起时,才会挂起.Lua的coroutine 是一个强大的概念,尽管它的几个主要应用都比较复杂. 1. Coroutine 基础 Lua将coroutine相关的所有函数封装在表coroutine 中