lua学习总结
来源:互联网 发布:淘宝怎么查快递到哪了 编辑:程序博客网 时间:2024/05/22 13:49
简述
Lua是一个很小的编程语言,很多人将其与Python高级语言进行比较。
Lua有以下的特点:
(1)纯C语言实现,源码小,可以很好地与C/C++融合。可自行编译,生成静态库。
(2)语法简单,灵活,易学。
我也同时学习了Python,相比之下,Lua精简,功能简单,可用的库少,但是语言的实现写得如此精简也很不错了!与C/C++程序结合就能显示它的强大能力,适用于要求可配置性很高的C/C++程序中,比如游戏。
如果想写纯脚本程序,那就选Python吧,它是强大,库多,喜欢单干。
好,我们学习Lua吧!
基础
数据类型
Lua的常用数据类型有:
(1)Nil (空) <==> C语言中的NULL
(2)number 所有数据,包含整数小数
(3)string 字串类型
(4)boolean 布尔类型 true, false
(5)function 函数类型
(6)table 表类型
其实,Lua中的数据类型远不止上面的这几个,比如file.
table在Lua中是最重要的数据类型,Lua的很多思想都是基于表来实现的,比如模块、对象。
boolean 除Nil与false为假以为,其它都为真。
string
\ 转义字符
\[
\]
\ddd 3个十进制的数据表示一个字符,高位填0
[[ ... ]] 表示多行字符串,其中字串无转义
a = [[ \t \n [[ ]]print(a)\t \n [[
当字符串被参于数值运算时,Lua会试图将字串转成数值
print("10"+ 1) --> 11print("123"* "12")--> 1476
当数值参于字串运算时,Lua也会尝试将其转换成字符串
print(123 .. 12)-->12312print(10 =="10") --> 永远都是false-- 除非print(10 == ("10"+ 0)) --> trueprint("10"== (10 .. ""))--> true
总之:操作符决定了两边操作数的转换类型。
表达式
(1)算术运算符 + - * / ^ (加减乘除幂)
(2)关系运算符 < > <= >= == ~= (不等于)
nil只与自己相等,table, usedate, function, 只比对象不比内容的值,相当于C语言中的指针比较
(3)逻辑运算符 and or not
and, or 的运算结果不是true与false
(4)优先级
^ 与 .. 是右连接
表结构
days = {"sun","Mon", "Tue","Wed", "Thu","Fri", "Sat"}print(days[0])--> nilprint(days[1])--> Sun
Polyline = { color = "blue", thickness = 2, npoints = 4,{x = 0, y = 0},{x = -10, y = 0},{x = -10, y = 10},{x = 0, y = 10}}Polyline["color"]--> "blue"Polyline.color --> "blue"Polyline[1] --> {x = 0, y = 0}Polyline[1].x --> 0
Person = {["name"] ="Peter", ["age"] = 28}-- 等价于Person = {name = "Peter", age = 28}{x=0, y=0} --> {["x"]=0, ["y"]=0}{"red","green", "blue"}--> {[1]="red", [2]="green", [3]="blue"}
基本语法
(1)多元素赋值
a, b = 10, 'Hi'--> 等价于a = 10; b = 'Hi'
(2)代码块chunk。
使用local创建的一个局部变量,可以避免命名冲突,而比全局变量高效。
(3)控制结构
<pre name="code" class="cpp">----------------------------------if condition1 then...else if condition2 then...else ...end----------------------------------while condition do...end----------------------------------repeat...until condition
----------------------------------
for var=exp1, exp2, exp3 do...end---> exp1: 初始值---> exp2: 终止值---> exp3: 步进for k in pairs(days) doprint(k .. ' = ' .. days[key])endfor i, val in ipairs(days) doprint(i .. ' = ' .. val)end
(4)函数
定义格式:
function func_name (arguments_list)...end
dofile "text.lua"table_print {a=12, b=30}
函数的返回值可以是多个:
function foo(a, b)return a+b, a-bendaa, bb = foo(32, 11)print(aa, bb) --> 43, 21
(5)闭包
Python与Lua都有闭包的特性,我记得好像Java也有,但是C与C++是没有的。
为了便于理解,我写一段C++的伪代码:
class CounterFunc{public: CounterFunc(int i*)
{ <span style="white-space:pre"></span>m_pCnt = i; } int operator()()
{<span style="white-space:pre"></span>++i;<span style="white-space:pre"></span>return i; }private: int *m_pCnt;}CounterFunc* newCounter(){ int *i = new int;
return new CounterFunc(i);}int main(){ CounterFunc &c1 = *newCounter() cout << c1() << endl; cout << c1() << endl;}
(6)非全局函数
表中的函数实现方式:
Lib = {}Lib.foo = function(x, y) return x+y end----------------------------------------------Lib = {
foo = function(x, y) return x+y end}----------------------------------------------Lib = {}function Lib.foo(x, y) return x+y end
local foo = function(x, y) return x+yend------------------------------------------------local function foo (x, y) return x+yend
(7)尾调函数
当函数的最后返回结果是调用另一个函数,称之为尾调函数。Lua的在调用尾调函数时,先是弹出当前函数的栈空间,然后再调用尾调函数,从而降低了函数层层调动过程中的栈消耗,非常适用于函数递归调用。
加载文件与运行
当我们需要加载与运行已有文件中的Lua代码时,可以用以下几种方式:
(1)loadstring( str ) --- 加载字串
f = loadstring "a = 12; print('a=' .. a)"f() --> a=12
f = loadstring "function() a = 12; print('a='..a) end"
(2)loadfile( file_name ) --- 加载文件
这个函数相当于从文件里读出string,然后再调用loadstring(file_text)实现加载功能。
(3)dofile( file_name ) --- 加载并执行文件
相当于loadfile()之后,返回一个函数,再调用这个函数。
function dofile( file_name ) local f = assert(loadfile(file_name)) f()end
(4)require( file_name )
这个函数是通过调用dofile()来实现的。不同的是,每次加载执行一个文件时,require()都会记录,避免重复加载。另外,如果给定的路径找不到文件,require()会到指定的路径下去找输到加载的文件。文件名称可以省去.lua后缀。
协同函数
关于这个功能,我的理解是:是非抢占式任务,由任务主动放弃执行权来达到任务切换的目的。
function foo (x, y) while ture do<span style="white-space:pre"></span>local a = x + y<span style="white-space:pre"></span>local b = x - y<span style="white-space:pre"></span>x, y = coroutine.yield(a, b) endend------------------------------------------co = coroutine.create(foo)print(coroutine.resume(co, 1, 2)) --> true 3 -1print(coroutine.resume(co, 7, 1)) --> true 8 6
(1)co = coroutine.create(foo),创建一个协同任务,返回co,此时co的状态为suspend。
(2)coroutine.resume(co, 1, 2),程序转而执行foo(x, y),x,y的传入的值正是resume()中的(1, 2)。
(3)foo(1, 2)执行到coroutine.yield(a, b),(a, b)分别为(3,-1)。程序执行yield(3, -1)切换到主任务,resume()函数返回第一个值为bool,后面的正是yield()中传入的参数。
(4)coroutine.resume(co, 7, 1),程序跳到foo()中的coroutine.yield()行继续执行。其中resume()函数中带的参数(7, 1),在foo()函数中,x, y = coroutine.yield() 通过返回值的形式赋给了(x, y)。
(5)跳到(3),如此重复。
可见,Lua并没有实现多任务并行执行,而是任务之间通过resume()与yield()函数进行切换。我想,其主要的作用还是用于将功能以任务的形式进行隔离,便于维护。
Metatables and Metamethods
元表与元方法,这是一个很重要的概念。可以为table设置或指定metatable,用于指定某些运算符对应的操作方法。
* setmetatable(table, meta_table) 设置元表
* getmetatable(table) 获取元表
这个元素,可以是个函数。
tb = {----> <metatable> = {__add = function : xxx 加法操作__sub = function : xxx 减法操作__mul = function : xxx 乘法操作...}[1] = 20[2] = 40...}
(1)算术运算
+ --> __add(a, b)- --> __sub(a, b)* --> __mul(a, b)/ --> __div(a, b)-负 --> __unm(a)^ --> __pow(a, b)
(2)关系运算
== --> __eq(a, b)< --> __lt(a, b)<= --> __le(a, b)
(3)库定义
__tostring = function(tb)
(4)表相关
__index = function(tb, key)__index = tb
__newindex = function(tb, key)
这两个东西,在类继承里用到。
环境变量
Lua环境放在全局变量 _G 中。可以用以下语句打印全局变量。
for n in pairs(_G) do print(n) end
</pre></div></div></div><div id="highlighter_474421" class="syntaxhighlighter lua"><div class="bar"><div class="toolbar"><pre code_snippet_id="358723" snippet_file_name="blog_20140522_27_6186527" name="code" class="cpp">a = 5print(_G["a"]) --> 5
在非全局域,防止访问到全局域
do a = 'Hi' setfenv(1, {_G = _G}) _G.print(_G.a) --> Hiend
- LUA学习总结
- lua学习总结
- lua学习总结
- lua学习总结
- Lua 语言学习总结
- lua 学习总结
- 【Lua学习笔记】Lua常用知识点总结
- 《Programming in Lua》学习总结
- lua 学习总结1:随笔
- Lua学习之metatable总结
- Lua学习之coroutine总结
- Lua学习总结(表达式)
- Lua学习总结(函数)
- Lua 学习小知识点总结
- lua :学习总结2,理解lua中Weak Table
- lua学习笔记---综合使用总结
- lua学习总结——C API
- Lua学习总结——内存管理
- 常用的设计模式场景
- Linux安装Oracle JDK替换OpenJDK详解
- 《Programming in Lua 3》读书笔记(二)
- Python参考手册(第4版) 学习笔记1
- 纯js的ajax readyState不返回4,jquery的$.ajax执行error,status200且数据可显示
- lua学习总结
- PHP 杂谈 坑爹的file_exists
- java保留两位小数4种方法
- Python参考手册(第4版) 学习笔记2
- POJ2080_Calendar(模拟)
- zoj 3129 Japan
- springMVC3学习--Interceptor拦截器
- java反射详解
- Boost 库多线程编程三