lua 函数 默认值_简明lua教程

lua 函数 默认值_简明lua教程自己整理的 lua 快速自学文档 供参考 liststart LUA 基本语法 LUA 常用函数 技巧集 APIreference 参考资料 listend LUA 基本语法 1 1 全局变量不需要声明 b nil 删除一个全局变量 print b amp g

自己整理的lua快速自学文档,供参考。

—————list start——————

【LUA基本语法】

【LUA常用函数】

【技巧集】

【API reference】

【参考资料】

—————list end——————–

【LUA基本语法】

1.1 全局变量不需要声明

b = nil

删除一个全局变量 print(b) –>

nil

1.2 退出LUA的方法

Ctrl-D(linux) Ctrl-Z(DOS/Windows) 调用OS库的函数

os.exit()

1.3 执行lua的chunk方法

执行一系列:lua

-l

-l

在交互模式下调用dofile函数

>dofile(“”)

1.4 注释

注意:Lua是大小写敏感的.

注释:单行注释:–

多行注释:–[[ –]]

1.5条件判断

在控制结构的条件中除了false和nil为假,其他值都为真。所以Lua认为0和空串都是真。

对于Table,Function和Userdata类型的数据,只有 == 和 ~=可以用。相等表示两个变量

引用的是同一个数据。比如:

a={1,2}

b=a

print(a==b, a~=b) — true, false

a={1,2}

b={1,2}

print(a==b, a~=b) — false, true

1.6 连接运算符

print(10 .. 12) –> 1012

1.7 逻辑运算符

逻辑运算符认为false和nil是假(false),其他为真,0也是true.

and的优先级比or高。

a and b — 如果a为false,则返回a,否则返回b

a or b — 如果a为true,则返回a,否则返回b

如果x为false或者nil则给x赋初始值v

x = x or v

C语言中的三元运算符

a ? b : c

(a and b) or c

1.8 引用表中成员

w = {x=0, y=0, label=”console”}

print(w.x) –> 0

print(w[“x”]) –> 0

1.9 迭代器

function list_iter (t)

local i =

0

local n =

table.getn(t)

return

function ()

i = i + 1

if i <= n then return t[i] end

end

end

t = {10, 20, 30}

for element in list_iter(t) do

print(element)

end

1.10 for循环

– 第一种:数值循环

for var=exp1,exp2,exp3 do

loop-part

end

for将用exp3作为step从exp1(初始值)到exp2(终止值),执行loop-part。

其中exp3可以省略,默认step=1

– 第二种:范性for

for in

do

end

是一个或多个以逗号分割的变量名列表,是一个或多

个以逗号分割的表达式列表,通常情况下exp-list只有一个值:迭代工厂的调用。

变量列表中第一个变量为控制变量,其值为nil时循环结束。

表达式应该返回范性for需要的三个值:迭代函数,状态常量和控制变量;

表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略;

将状态常量和控制变量作为参数调用迭代函数;

迭代函数返回的值赋给变量列表。

1.11 错误处理

error函数抛出异常

assert调用抛出异常

pcall函数调用

1.12 协同程序

coroutine.create()

coroutine.resume(,[传给协同程序的参数列表])

resume函数的返回值除了true或false以外,还有yield的所有参数

1.13 __le和__lt __eq

一般实现__le后,还要实现__lt 和__eq

Set.mt.__lt = function (a,b)

return a <= b and not (b

<= a)

end

Set.mt.__eq = function (a,b)

return a <= b and b

<= a

end

1.14 有默认值的表实现(所有表共享同一个metatable)

local key = {} — unique key

local mt = {__index = function(t) return t[key] end}

function setDefault (t, d)

t[key] =

d

setmetatable(t, mt)

end

–>上面的写法,每一个表占用一个空间存储默认值d

tab = {x=10, y=20}

print(tab.x, tab.z) –> 10 nil

setDefault(tab, 0)

print(tab.x, tab.z) –> 10 0

1.15 只读的表实现

每一个只读代理有一个单独的新的metatable,使用__index指向原始表

1.16 监控表的实现

设置一个空表,这样就会总能触发__index和__newindex

1.17 LUA全局变量

枚举所有全局变量

for n in pairs(_G) do print(n) end

打印制定全局变量,例如:

print(_G[“loadfile”])

1.18 __index

metamethod P108

__index metamethod不需要非是一个函数,他也可以是一个表。

但它是一个函数的时候,Lua将table和缺少的域作为参数调用这个函数;

当他是一个表的时候,Lua将在这个表中看是否有缺少的域。

1.19 包 module

http://blog.csdn.net/chenyufei1013/archive/2009/08/12/.aspx

module 指令运行完后,整个环境被压栈,所以前面全局的东西再看不见了。

local print=print

module(“test”)

print(…)

或者

local _G=_G

module(“test”)

_G.print(…)

或者

module(“test”,package.seeall)

print(…)

1.20 C API

#define lua_open() luaL_newstate()

lua_State *L = lua_open();

lua_open()

luaL_newstate()

luaL_openlibs

luaopen_base(L);

luaopen_table(L);

luaopen_io(L);

luaopen_string(L);

luaopen_math(L);

空值(nil)用lua_pushnil

数值型(double)用lua_pushnumber

布尔型(在C中用整数表示)用lua_pushboolean

任意的字符串(char*类型,允许包含’\0’字符)用lua_pushlstring

C语言风格(以’\0’结束)的字符串(const char*)用lua_pushstring

lua_tostring(L, -1) 以字符串的形式返回栈顶的值

API提供了一套lua_is*函数来检查一个元素是否是一个指定的类型

lua_getglobal(L, )

获得lua文件中的变量并压入栈中

一般为module名或者table名

lua_gettable(L,

用lua_gettable取出table中的元素并压入栈中。

例如:

lua_getglobal(L, “background”); //将表压栈

lua_pushstring(L, “red”) //首先将key压栈

lua_gettable(L, -2); –> get background[“red”]

一种简便的方法如下:直接使用lua_getfield

lua_getfield(L, ,

)

name>相对应的global索引,global可能是上次

lua_pop(L, )

在调用脚本之前可以在C语言中设置global变量或者table对象

然后在脚本中就可以执行C语言中设置的变量或对象了。

lua_pushstring

lua_newtable(L)

lua_setfield(L,

)

//栈顶必须是要设置的

lua_setglobal(L,

) //栈顶必须有要设置的元素

例如:

lua_pushnumber(L, ct1.red/MAX_COLOR);

lua_setfield(L, -2, “r”);

lua_pushnumber(L, ct1.green/MAX_COLOR);

lua_setfield(L, -2, “g”);

lua_setglobal(L, “RED”);

LUA调用C文件中的函数方法:

需要注册函数

lua_pushcfunction(l, l_sin);

lua_setglobal(l, “mysin”);

C调用LUA文件中的函数方法:

lua_getglobal(L,

name>)

lua_push*() //例如lua_pushnumber(L, x)

lua_pcall(L, ,

,

)

例如lua_pcall(L, 2, 1, 0)

//获得返回值

lua_to*() //例如lua_tonumber(L, -1);

lua_pop(L,1)

C作为库文件被Lua调用,C文件统一接口函数

luaopen_,

必须和dll保持一致

例如:

#define _EXPORT extern “C” __declspec(dllexport)

_EXPORT int luaopen_capi_mytestlib(lua_State *L)

{

struct

luaL_reg driver[] = {

{“average”, average1},

{NULL, NULL},};

luaL_register(L, “mylib”, driver);

//luaL_openlib(L, “mylib”, driver, 0);

return

1;

}

li情况

按照网上所说,LUA加载C动态库搞了一把,终于在LINUX下搞通了,白白浪费许多时间。

总结几条:

1.动态库要供LUA调用的function,其定义要符合:

typedef int function(lua_State *L)

这个一般大家都知道

2.在动态库调用LUA注册:

将要调用的函数放到这个结构体里:

struct luaL_Reg lib[] =

{}

在动态库的入口函数里调用luaL_register将这个结构体注册

3.入口函数定义很重要,一定是要定义成:

int luaopen_XXX(lua_State *L)

否则就提示找不到动态库,

在这个入口函数注册结构体时,要注册成:

luaL_register(L,”XXX”,lib);

与入口函数的luaopen_XXX的XXX要一致。

4.在写脚本的时候,使用require(“XXX”),就是入口函数的luaopen_后面的XXX,注意大小写敏感

5.编译生成的动态库命令成XXX.so,对,同入口函数的luaopen_后面的XXX一致

SAMPLE:

C文件如下:

#include

#include “lua/lua.h”

#include “lua/lualib.h”

#include “lua/lauxlib.h”

static int add(lua_State *L)

{

int a,b,c;

a = lua_tonumber(L,1);

b = lua_tonumber(L,2);

c = a+b;

lua_pushnumber(L,c);

printf(“test hello!!!\r\n”);

return 1;

}

static const struct luaL_Reg lib[] =

{

{“testadd”,add},

{NULL,NULL}

};

int luaopen_testlib(lua_State *L)

{

luaL_register(L,”testlib”,lib);

return 1;

}

编译: gcc test.c -fPIC -shared -o testlib.so

脚本编写:

require(“testlib”)

c = testlib.testadd(15,25)

print(“The result is “,c);

1.22 面向对象

1) 对象 类

setmetatable(a, {__index = b})

a相当于对象,b相当于类;对象a调用任何不存在的成员都会到对象b中查找

一个类的简单实现:

local _G = _G;

module “packparse”

function New(self,o)

_G.setmetatable(o,self);

self.__index = self;

return o;

end

1.23 userdata用途

在Lua中自定义类型,该类型由C函数操作。Lua为这种情况提供专门提供一个基本的类型:

userdata。一个userdatum提供了一个在Lua中没有预定义操作的raw内存区域。

每次我们访问数组的时候,我们都要检查他是否有一个正确的metatable。

因为Lua代码不能改变userdatum的metatable,所以他不会伪造我们的代码。

【LUA常用函数】

2.1 type函数,测试给定变量或者值的类型

2.2 字符串处理函数 字符串与数值转换函数

替换函数, string.gsub(a, “one”, “another”)

字符串 数字间转换函数 tonumber tostring

2.3 io读写函数

io.read io.write

io.open打开文件??

2.4 遍历for循环函数pairs ipairs

pairs能遍历所有的元素,ipairs只能遍历数组

–for i in pairs(days) do

— print(days[i])

–end –for i,value in pairs(days) do

— print(value)

–end

ipairs使用key的顺序1、2、pairs使用表的自然存储顺序。

2.5 table表处理函数

table.getn(

name>)

2.6 string字符串处理函数

前缀 后缀

string.sub(s, 1, j)返回字符串s的长度为j的前缀;

string.sub(s, j, -1)返回从第j个字符开始的后缀;

string.char将数字转换成整数

string.byte将字符串制定位置的字符转换成整数

字符串部分替换string.gsub(目标串,模式串,替换串,替换次数)

例如:计算空格出现次数 _, count = string.gsub(str, ” “, ” “)

string.sub(s,i,j)函数截取字符串s的从第i个字符到第j个字符之间的串

string.find(目标串,要查找串)

例如:

s = “Deadline is 30/05/1999, firm”

date = “%d%d/%d%d/%d%d%d%d”

print(string.sub(s, string.find(s, date))) –>

30/05/1999

gsub进行子串替换

s = “\\command{some

text}”

print(s)

s = string.gsub(s, “\\(%a+){(.-)}”,

“%2%1>”)

print(s)

–> some

text

2.7 模式匹配

*和-区别

‘*’进行最长匹配

test = “int x; int y; “

print(string.gsub(test, “/%*.*%*/”,

“”))

–> int x;

‘-’进行最短匹配

test = “int x; int y; “

print(string.gsub(test, “/%*.-%*/”,

“”))

–> int x;

int y;

匹配位置定位 ^ $

string.find(s, “^[+-]?%d+$”) — 检查字符串s是否以数字开头

string.find(s, “^%d”) — 检查字符串s是否以数字开头

‘%b’ 用来匹配对称的字符 常用的这种模式有:’%b()’ ,’%b[]’,’%b%{%}’ 和

‘%b<>‘

2.8 模式捕获

pair = “name = Anna”

_, _, key, value = string.find(pair, “(%a+)%s*=%s*(%a+)”)

print(key, value) –> name Anna

2.9 require函数

2.10 产生随机数

math.random(0,1); 产生随机整数0~1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【技巧集】

X. 数组里面的元素可以是函数

Q: lua_pushliteral和lua_pushstring有何区别?

A:

通常在push字符串字面值时使用lua_pushliteral,在push字符串指针是使用lua_pushstring。

原因是前者通过sizeof(字符串字面值)/sizeof(char)计算长度,而后者通过strlen计算长度。

因此前者只能push字符串字面值,但速度比后者快。而后者既可push字符串字面值,也可push字符串指针。

Q: luaL_loadfile, luaL_loadstring, luaL_loadbuffer的区别?

A: luaL_loadfile把文件内容作为chunk,并在内部调用lua_load

luaL_loadstring把字符串栈转为buffer调用luaL_loadbuffer

luaL_loadbuffer把buffer的内容作为chunk,并在内部调用lua_load

lua_load则将chunk作为lua

function压栈,并具有自动分析chunk是二进制(luac)还是普通文本的能力

Q: lua_pcall, lua_resume的区别?

A:

lua_resume只可以用在coroutine中,当coroutine没有任何yield时,lua_resume可以用lua_pcall代替

LUA的优点:

昨天你问为什么要用LUA解析报文,因为用C++解析报文,当报文的内容更改,C++代码也要作修改,

要重新编译,服务器要重新启动,但是在LUA中处理解析的话,可以热更新。LUA也可以做配置,当

然可以采用xml,但用就用一种,方便管理。用脚本也就是为了应付灵活多变的需求,我们是做游戏,

需求经常变动。比如要增加一个新功能,直接用LUA写下,做个客户端管理工具,给他发个包,让他

加载下指定的LUA文件,服务器在不重启的情况下,就能提供新的功能了,给用户的体验很好,不会

动不动停机维护

LUA编译环境:

C/C++ -> 代码生成 -> 多线程调试(/MT

/MTd)

头文件要 extern “C”

extern “C” {

#include “./lua/lua.h”

#include “./lua/lauxlib.h”

#include “./lua/lualib.h”

};

调用类中方法

int ret = luaL_dofile(m_pLua,filepath.c_str());

if(ret!=0) {

。。。

}

lua_getglobal(m_pLua,”globlePath”);

lua_getfield(m_pLua,-1,”SetPath”);

ret = lua_pcall(m_pLua,1,0,0);

lua_settop(m_pLua,0);

获得lua文件中的全局变量

int ret = luaL_dofile(m_pLua,filepath.c_str());

if(ret!=0) {

。。。

}

lua_getglobal(m_pLua,”selfPort”);

m_port = lua_tointeger(m_pLua,-1);或者m_ManageSvr.strIp =

lua_tostring(m_pLua,-1);

lua_pop(m_pLua,1);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【API reference】

X. lua_pushnumber

void lua_pushnumber (lua_State *L, lua_Number n);

Pushes a number with value n onto the stack.

X. lua_setfield

void lua_setfield (lua_State *L, int index, const char *k);

Does the equivalent to t[k] = v, where t is the value at the given

valid index index and v is the

value at the top of the stack, This function pops the value from

the stack. As in Lua, this function

may trigger a metamethod for the “newindex” event.

X. lua_getfield

Pushes onto the stack the value t[k], where t is the value at the

given valid index index. As in Lua, this

function may trigger a metamethod for the “index” event

1. luaL_dofile

int luaL_dofile (lua_State *L, const char *filename);

Loads and runs the given file. It is defined as the following

macro:

2. lua_getglobal

void lua_getglobal (lua_State *L, const char *name);

Pushes onto the stack the value of the global name. It is defined

as a macro

4. lua_pushstring

Pushes the zero-terminated string pointed to by s onto the stack.

Lua makes (or reuses) an internal copy of the

given string, so the memory at s can be freed or

reused immediately after the function returns. The string cannot

contain embedded zeros; it is assumed to end at

the first zero.

5. lua_pcall

lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

Calls a function in protected mode.

Both nargs and nresults have the same meaning as in lua_call. If

there are no errors during the call,

lua_pcall behaves exactly like lua_call. However, if there is any

error, lua_pcall catches it, pushes

a single value on the stack (the error message), and returns an

error code. Like lua_call, lua_pcall

always removes the function and its arguments from the stack.

6. lua_settop

void lua_settop (lua_State *L, int index);

Accepts any acceptable index, or 0, and sets the stack top to

this index.

If the new top is larger than the old one, then the new elements

are filled with nil. If index is 0, then all stack

elements are removed.

7. 压入参数

lua_pushnumber

lua_pushstring

8. lua_pop

void lua_pop (lua_State *L, int n);

Pops n elements from the stack.

9. lua_pushcfunction

Pushes a C function onto the stack. This function receives a

pointer to a C function and pushes onto

the stack a Lua value of type function that, when called, invokes

the corresponding C function.

10. lua_setglobal

void lua_setglobal (lua_State *L, const char *name);

Pops a value from the stack and sets it as the new value of global

name. It is defined as a macro:

11. lua_isuserdata

Returns 1 if the value at the given acceptable index is a userdata

(either full or light),

and 0 otherwise.

12. lua_touserdata

void *lua_touserdata (lua_State *L, int index);

If the value at the given acceptable index is a full userdata,

returns its block address.

If the value is a light userdata, returns its pointer. Otherwise,

returns NULL.

13.,luaL_checkudata

检查在栈中指定位置的对象是否为带有给定名字的metatable的usertatum。如果对象不存在正确的metatable,

返回NULL(或者它不是一个userdata);否则,返回userdata的地址。

14. luaL_newmetatable

int luaL_newmetatable (lua_State *L, const char *tname);

把表存入注册表

If the registry already has the key tname, returns 0. Otherwise,

creates a new table to be used

as a metatable for userdata, adds it to the

registry with key tname, and returns 1.

15. lua_settop

lua_settop设置栈顶(也就是堆栈中的元素个数)为一个指定的值。如果开始的栈顶高于新的栈顶,

顶部的值被丢弃。否则,为了得到指定的大小这个函数压入相应个数的空值(nil)到栈上。

特别的,lua_settop(L,0)清空堆栈。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/177212.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月26日 下午8:02
下一篇 2026年3月26日 下午8:03


相关推荐

  • ubuntu搭建samba服务器_搭建webdav

    ubuntu搭建samba服务器_搭建webdav1、下载安装samba服务sudoapt-getinstallsamba2、修改smb配置文件,设置共享目录a)配置文件:/etc/samba/smb.confb)进到该目录:cd/etc/sambac)修改前备份:sudocpsmb.confsmb.conf_bakd)修改配置文件,设置共享目录:sudovismb.conf参考修改内容(例:共享目录/home/samba_share)[samba_share]comment=…

    2026年3月8日
    3
  • MySql中的longtext字段的返回问题「建议收藏」

    MySql中的longtext字段的返回问题「建议收藏」最近开发中用到了longtext这种字段。在mysql中该字段的最大长度为4G如下图所示开发中遇到的一个问题就是。例如有个article表,然后我们的页面要将数据以列表的形式展示到前端(只显示几个字段,如作者,标题等等,例如放到table中显示多条记录),但是是将该表中的所有信息都查出来,然后当用户点击某条记录的时候,会跳到详情页,在显示出详细的信息。这样当数据量比较多的时候,或者文本…

    2022年5月15日
    37
  • 批量归一化和层归一化_数据归一化公式

    批量归一化和层归一化_数据归一化公式一、背景意义本篇博文主要讲解2015年深度学习领域非常棒的一篇文献:《BatchNormalization:AcceleratingDeepNetworkTrainingby ReducingInternalCovariateShift》,这个算法目前已经被大量的应用,最新的文献算法很多都会引用这个算法,进行网络训练,可见其强大之处非同一般啊,采用这个方法网络的训练速度快到…

    2022年10月11日
    4
  • OutOfMemory及其解决方法「建议收藏」

    一、内存溢出类型1、java.lang.OutOfMemoryError:PermGenspaceJVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果webapp用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,

    2022年4月10日
    724
  • 详解结构方程模型,路径分析方法有哪些_结构方程模型的数据要求

    详解结构方程模型,路径分析方法有哪些_结构方程模型的数据要求一、简介微生物群落研究逐渐从单一的群落结构研究转向分析群落与环境因素的关联互作机制研究当中,典型的环境因子分析方法有CCA/RDA、互作网络图、VPA分析等,这些分析能帮助我们逐一比较待选的环境因子与微生物群落数据间的关联性,细致挖掘对群落结构有影响的个别环境因子。需要注意到的是,环境对微生物群落的影响是间接的,例如:气温因素影响了植物的生长状态,植物的生长状态的变化影响土壤微生物的群落结构……

    2022年8月24日
    10
  • 《深入浅出Python机器学习》读书笔记 第一章 概述

    《深入浅出Python机器学习》读书笔记 第一章 概述《深入浅出Python机器学习》读书笔记,第一章概述

    2022年8月31日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号