admin 管理员组文章数量: 887032
2023年12月19日发(作者:excel常用教程)
C/C++程序员的Lua快速入门指南Robert Z2010-1
前言 本文针对的读者是希望了解Lua或者迅速抓住Lua的关键概念和编程模式的有经验的C/C++程序员。因此本文并不打算教给读者诸如条件语句的语法或者函数定义的方式等等显而易见的东西,以及一些诸如变量、函数等现代编程语言普遍的基本概念。本文只打算告诉读者Lua那些与C/C++相比显著不同的特性以及它们实际上带来了怎样截然不同于C/C++的思维方式。不要小看它们,它们即将颠覆你传统的C/C++的世界观! 本文一共分初阶、进阶和高阶三大部分,每个部分又有若干章节。读者应当从头至尾循序渐进的阅读,但是标有“*”号的章节(主要讨论OO在Lua中的实现方式)可以略去而不影响对后面内容的理解(但是作者不建议这么做)。读者只要把前两部分完成就可以胜任Lua开发的绝大部分任务。高阶部分可作为选择。 本文不打算取代Lua参考手册或者一本全面的Lua教科书,因此对一些重要的Lua函数也未做足够的说明。在阅读的同时或者之后,读者应当多多参考Lua的正式文档或者其他相关材料(附录里列出了一些常用的Lua参考资料)。
请访问本文的在线版本获得最新更新。另外,作者还有一个开源的Lua调试器——RLdb以及一个讨论Lua的站点,欢迎访问。 欢迎读者来信反馈意见。
初阶话题数据类型函数表
简单对象的实现*简单继承*
数据类型八种类型:数值(number)内部以double表示的数值类型。字符串(string)由任意字符组成的以零结尾的字符序列;不等价于C字符串,而是其超集。布尔(boolean)只有“true”或者“false”两个值的逻辑类型。函数(function)基本的Lua对象;不简单等同于C的函数或函数指针;Lua的关键概念之一。表(table)异构的Hash表;也是Lua的关键概念。userdataC用户定义的C数据结构;脚本用户只能使用它,不能定义。线程(thread)Lua协作线程(coroutine);与一般操作系统的抢占式线程不一样。nil代表什么也没有,在mouzhong可以与C的NULL作类比,但它不是空指针。
函数function foo(a, b, c) local sum = a + b return sum, c --函数可以返回多个值endr1, r2 = foo(1, '123', 'hello') --平行赋值print(r1, r2)输出结果:124 hello
函数(续)函数定义用关键字function定义函数,以关键字end结束函数可以返回多个值return a, b, c, ...平行赋值a, b = c, d局部变量用关键字local定义。如果没有用local定义,即使在函数内部定义的变量也是全局变量!全局变量没有用local定义的变量都是全局变量(并不总是这样,稍后读者会看到Lua还有一种叫做“外部局部变量”的变量类型)。前面的代码定义了三个全局变量:foo、r1和r2
表a = { }b = { x = 1, ["hello, "] = "world!" }g = "ni, hao!"a[1] = 100a["a table"] = bfunction foo()endfunction bar()enda[foo] = bar--分别穷举表a和bfor k, v in pairs(a) do
print(k, "=>", v)
endprint("----------------------------")for k, v in pairs(b) do
print(k, "=>", v)
end输出结果:1 => 100a table => table: 003D7238astring => ni, hao!function:
003DBCE0 => function:
003DBD00----------------------------hello, => world!x => 1
表定义表的方式a = {}, b = {…}访问表的成员通过“.”或者“[]”运算符来访问表的成员。注意:表达式a.b等价于a[“b”],但不等价于a[b]表项的键和值任何类型的变量,除了nil,都可以做为表项的键或值。给一个表项的值赋nil意味着从表中删除这一项,比如令a.b = nil,则把表a中键为“b”的项删除。另外,如果访问一个不存在的表项,其值是nil。比如有c = a.b,但表a中没有键为“b”的项,则c等于nil。
一种简单的对象实现方式*function create(name, id) local obj = { name = name, id = id } function obj:SetName(name) = name end function obj:GetName() return end function obj:SetId(id) = id end function obj:GetId() return end return objendo1 = create("Sam", 001)print("o1's name:", o1:GetName(),
"o1's id:", o1:GetId())o1:SetId(100)o1:SetName("Lucy")print("o1's name:", o1:GetName(),
"o1's id:", o1:GetId())输出结果:o1's name: Sam o1's id: 1o1's name: Lucy o1's id: 100
一种简单的对象实现方式*(续)对象工厂模式如前面代码的create函数对象的表示方法用表来表示对象,把对象的数据和方法都放在一张表内,虽然没有隐藏私有成员,但对于简单脚本来说完全可以接受。成员方法的定义function obj:method(a1, a2, ...) … end 等价于function (self, a1, a2, ...) … end 等价于 = function (self, a1, a2, ...) … end成员方法的调用obj:method(a1, a2, …) 等价于(obj, a1, a2, ...)
简单继承*function createRobot(name, id) local obj = { name = name, id = id } function obj:SetName(name) = name end function obj:GetName() return end function obj:GetId() return end return objendfunction createFootballRobot(name,
id, position) local obj = createRobot(name, id) on = "right back" function obj:SetPosition(p) on = p end function obj:GetPosition() return on end return objend
简单继承*(续)优点:简单、直观缺点:传统、不够动态
进阶话题函数闭包(function closure)基于对象的实现方式(object based programming)*元表(metatable)基于原型的继承(prototype based inheritance)*函数环境(function envrionment)包(package)
函数闭包function createCountdownTimer(second) local ms = second * 1000 local function countDown() ms = ms - 1 return ms end return countDownendtimer1 = createCountdownTimer(1)for i = 1, 3 do print(timer1())endprint("------------")timer2 = createCountdownTimer(1)for i = 1, 3 do print(timer2())end输出结果:999998997------------999998997
函数闭包(续)Upvalue一个函数所使用的定义在它的函数体之外的局部变量(external local
variable)称为这个函数的upvalue。在前面的代码中,函数countDown使用的定义在函数createCountdownTimer中的局部变量ms就是countDown的upvalue,但ms对createCountdownTimer而言只是一个局部变量,不是upvalue。Upvalue是Lua不同于C/C++的特有属性。函数闭包一个函数和它的所有upvalue构成了一个函数闭包。Lua函数闭包与C函数的比较Lua函数闭包使函数在几次调用间具有保持它自己状态的能力,从这个意义上说,带静态局部变量的C函数与之相似。但二者qish截然不同:前者是编程语言的一种基本对象,后者只是一个静态地址的符号名称;前者可以产生同一类型的若干实例,每个实例都有自己的状态,而后者只是一个静态的符号,谈不上什么实例化。
基于对象的实现方式*function create(name, id) local data = { name = name, id = id
} local obj = {} function e(name) = name end function e() return end function (id) = id end function () return end return objendo1 = create("Sam", 001)o2 = create("Bob", 007)(100)print("o1's id:", (), "o2's id:",
())e("Lucy")print("o1's name:", e(),
"o2's name:", e())
输出结果:o1's id: 100 o2's id: 7o1's name: Sam o2's name: Lucy
基于对象的实现方式*(续)实现方式
把需要隐藏的成员放在一张表里,把该表作为公有成员函数的upvalue;再把所有的共有成员放在另一张表里,把这张表作为对象。局限性
如果考虑到对象继承及多态,这种方法就不够灵活。但另一方面,脚本编程是否需要继承和多态要视情况而定。
元表t = {}m = { a = " and ", b = "Li Lei", c = "Han Meimei" }setmetatable(t, { __index = m}) --表{ __index=m }作为表t的元表for k, v in pairs(t) do --穷举表t print(k, v)endprint("-------------")print(t.b, t.a, t.c)输出结果:-------------Li Lei and Han Meimei
元表(续)function add(t1, t2) --‘#’运算符取表长度 assert(#t1 == #t2)
local length = #t1 for i = 1, length do t1[i] = t1[i] + t2[i] end return t1end
--setmetatable返回被设置的表t1 = setmetatable({ 1, 2, 3}, { __add
= add })t2 = setmetatable({ 10, 20, 30 }, {
__add = add })t1 = t1 + t2for i = 1, #t1 do print(t1[i])end
输出结果:112233
元表(续)元表元表本身只是一个普通的表,一般带有一些特殊的事件回调函数,通过 setmetatable被设置到某个对象上进而影响这个对象的行为。回调事件(比如__index和__add)由Lua定义而回调函数由脚本用户定义并在相应事件发生时由Lua虚拟机调用。以前面的代码为例,表的加法运算在缺省状态下将产生异常,但是设置了适当元表的表就可以进行加法运算了——Lua虚拟机将在表做加法运算时调用用户定义的__add回调函数。重载运算符从前面的例子里读者可能已经意识到在Lua里运算符可以被重载!确实是这样,不仅是“+”运算,几乎所有的对象的运算符都可以被重载!元表与C++虚表的比较
元表是可以影响一个对象行为的“元”对象,而虚表只是用于定位对象行为(方法)的概念上的对象。元表可以在运行时动态改变,而虚表是由编译器产生的,因此是静态、不可改变的。更多内容元表对Lua意义重大,内容十分丰富。作者建议读者参考Lua手册获取更多了解。
基于原型的继承*Robot = { name = "Sam", id = 001 }function Robot:New(extension) local t = setmetatable(extension or { }, self)function FootballRobot:SetPosition(p) on = pendfunction FootballRobot:GetPosition() self.__index = self return tendfunction Robot:SetName(name) = nameendfunction Robot:GetName() return dfunction Robot:SetId(id) = idendfunction Robot:GetId() return obot = Robot:New()print("robot's name:", robot:GetName())print("robot's id:", robot:GetId())print("-----------------")FootballRobot = Robot:New( {position = "right back"}) return onendfr = FootballRobot:New()print("fr's position:", fr:GetPosition())print("fr's name:", fr:GetName())print("fr's id:", fr:GetId())print("-----------------")fr:SetName("Bob")print("fr's name:", fr:GetName())print("robot's name:", robot:GetName())输出结果:robot's name: Samrobot's id: 1-----------------fr's position: right backfr's name: Samfr's id: 1-----------------fr's name: Bobrobot's name: Sam
基于原型的继承*(续)prototype模式一个对象既是一个普通的对象,同时也可以作为创建其他对象的原型的对象(即类对象,class object);动态的改变原型对象的属性就可以动态的影响所有基于此原型的对象;另外,基于一个原型被创建出来的对象可以重载任何属于这个原型对象的方法、属性而不影响原型对象;同时,基于原型被创建出来的对象还可以作为原型来创建其他对象。
函数环境function foo() print(g or "No g defined!")endfoo()setfenv(foo, { g = 100, print = print })
foo()print(g or "No g defined!")输出结果:No g defined!100No g defined!--设置foo的环境为表{ g=100, ...}
函数环境(续)函数环境函数环境就是一个函数在运行时所能访问的全局变量的集合,装在一个表中。在缺省状态下,一个函数与定义它的函数共享同一个环境;但是每个函数都可以有自己的环境,通过setfenv来设定。在前面的代码中,函数foo的缺省环境里没有定义变量g,因此第一次执行foo, g为nil,表达式g or "No g defined!"的值就是"No g defined!"。随后,foo被指定了一个环境 { g = 100, print = print }。这个环境定义了(全局)变量g,以及打印函数print,因此第二次执行foo,g的值就是100。但是在定义函数foo的函数的环境下,g仍然是一个未定义的变量。应用函数环境是Lua相对于C/C++所独有的特性之一。读者可能想知道这个奇怪的性质究竟有什么用。其实它大有所为:利用它可以实现函数执行的“安全沙箱”;另外Lua的包的实现也依赖它。
包--:pack = require "mypack" --导入包print(ver or "No ver defined!")print()print(aFunInMyPack or
"No aFunInMyPack defined!")MyPack()print(aFuncFromMyPack or
"No aFuncFromMyPack defined!")aFuncFromMyPack()--:module(..., ) --定义包ver = "0.1 alpha"function aFunInMyPack() print("Hello!")end_romMyPack =
aFunInMyPack
包(续)执行的输出结果:No ver defined!0.1 alphaNo aFunInMyPack defined!Hello!function: 003CBFC0Hello!
包(续)包包是一种组织代码的方式。实现方式一般在一个Lua文件内以module调用开始定义一个包。module调用同时为这个Lua 文件定义了一个新的函数环境。这里有必要搞清楚这样一个事实:Lua虚拟机把一个Lua文件的内容当作一个函数体来处理(这意味着你可以从一个Lua文件中返回一些值或者从文件外面接收一些函数参数!)。设定了一个新的函数环境后,Lua文件所定义的所有全局变量都保存在那个表里。以前面的代码为例, “module(..., )”的意思是定义一个包,并且在包的函数环境里可以看见require包的函数的环境里的全局变量(如果没有 ,在包里就不可访问print函数)。使用方式一般用require函数来导入一个包,要导入的包必须被置于包路径(package
path)上。包路径可以通过或者环境变量来设定。一般来说,当前工作路径总是在包路径中。更多包的内容十分丰富,请参考Lua手册进一步了解更多有关包的说明。
高阶话题迭代(iteration)协作线程(coroutine)
迭代function enum(array) local index = 1 return function() --返回迭代函数 local ret = array[index] index = index + 1 return ret endendfunction foreach(array, action) for element in enum(array) do action(element) endendforeach({1, 2, 3}, print)输出结果:123
迭代(续)迭代迭代是for语句的一种特殊形式,for语句可以驱动迭代函数对一个给定集合进行遍历。正式、完备的语法说明较复杂,请参考Lua手册。实现如前面代码所示:enum函数返回一个匿名的迭代函数,for语句每次调用该迭代函数都得到一个值(通过element变量引用),若该值为nil,则for循环结束。
协作线程function producer() return ( function (salt) local t = { 1, 2, 3 } for i = 1, #t do salt =
(t[i] + salt) end end )end输出结果:1110210003END!function consumer(prod) local salt = 10 while true do local running, product = (prod, salt) salt = salt * salt if running then print(product or "END!") else break end endendconsumer(producer())
协作线程(续)协作线程Lua的线程对象。不同于一般操作系统所采取的抢占式线程,Lua采取了一种合作式线程。也就是说,只有在一个线程主动放弃处理器时,另一个线程才能执行。创建协作线程通过可以创建一个协作线程,该函数接收一个函数类型的参数作为线程的执行体,返回一个线程对象。启动或继续线程通过可以启动一个线程或者继续一个挂起的线程。该函数接收一个线程对象以及其他需要传递给该线程的参数。线程可以通过线程函数的参数或者调用的返回值来获取这些参数。当线程初次执行时,resume传递的参数通过线程函数的参数传递给线程,线程从线程函数开始执行;当线程由挂起转为执行时,resume传递的参数以yield调用返回值的形式传递给线程,线程从yield调用后继续执行。线程放弃调度线程调用暂停自己的执行,并把执行权返回给启动/继续它的线程;线程还可利用yield返回一些值给后者,这些值以resume调用的返回值的形式返回。
协作线程(续)function instream() return (function() while true do local line = ("*l") if line then (line) else break end end end)endfunction filter(ins) return (function() while true do local line = ins() if line then line = "** " .. line .. " **" (line) else break end end end)endfunction outstream(ins) while true do local line = ins() if line then print(line) else break end endendoutstream(filter(instream()))输入/输出结果:abc** abc **123** 123 **^Z
协作线程(续)Unix管道与Stream IO利用协作线程可以方便地设计出类似Unix管道或者Stream IO的结构。
协作线程(续)function enum(array) return (function() local len = #array for i = 1, len do (array[i]) end end)endfunction foreach(array, action) for element in enum(array) do action(element) endendforeach({1, 2, 3}, print)输出结果:123
协作线程(续)另一种迭代方式协作线程可以作为for循环迭代器的另一种实现方式。虽然对于简单的数组遍历来说,没有必要这么做,但是考虑一下,如果需要遍历的数据集合是一个复杂数据结构,比如一棵树,那么协作线程在简化实现上就大有用武之地了。
附录 常用的Lua参考资料Lua参考手册(最正式、权威的Lua文档)Lua编程(在线版,同样具权威性的Lua教科书)Lua正式网站的文档页面(包含很多有价值的文档资料链接)Lua维基(最全面的Lua维基百科)LuaForge(最丰富的Lua开源代码基地)
Lua 5.1 Reference Manual - contents Lua 5.1 Reference Manual
The reference manual is the official definition of the Lua language. For a complete
introduction to Lua programming, see the book Programming in Lua.
This manual is also available as a book:
Lua 5.1 Reference Manual
by R. Ierusalimschy, L. H. de Figueiredo, W. Celes
, August 2006
ISBN 85-903798-3-3
Buy a copy of this book and help to support the Lua project.
start · contents · index · errata · previous versions · português · español · русский ·
magyar
Copyright © 2006-2008 , PUC-Rio. Freely available under the terms of the Lua license.
Contents●
1 - Introduction
2 - The Language
r
2.1 - Lexical Conventions
r
2.2 - Values and Types
■
2.2.1 - Coercion
r
2.3 - Variables
●
/manual/5.1/(第 1/6 页)2010-9-3 17:29:35
Lua 5.1 Reference Manual - contents2.4 - Statements
■
2.4.1 - Chunks
■
2.4.2 - Blocks
■
2.4.3 - Assignment
■
2.4.4 - Control Structures
■
2.4.5 - For Statement
■
2.4.6 - Function Calls as Statements
■
2.4.7 - Local Declarations
r
2.5 - Expressions
■
2.5.1 - Arithmetic Operators
■
2.5.2 - Relational Operators
■
2.5.3 - Logical Operators
■
2.5.4 - Concatenation
■
2.5.5 - The Length Operator
■
2.5.6 - Precedence
■
2.5.7 - Table Constructors
■
2.5.8 - Function Calls
■
2.5.9 - Function Definitions
r
2.6 - Visibility Rules
r
2.7 - Error Handling
r
2.8 - Metatables
r
2.9 - Environments
r
2.10 - Garbage Collection
■
2.10.1 - Garbage-Collection Metamethods
■
2.10.2 - Weak Tables
r
2.11 - Coroutines
r
●
3 - The Application Program Interface
r
3.1 - The Stack
r
3.2 - Stack Size
r
3.3 - Pseudo-Indices
r
3.4 - C Closures
r
3.5 - Registry
r
3.6 - Error Handling in C
r
3.7 - Functions and Types
r
3.8 - The Debug Interface
4 - The Auxiliary Library
●
/manual/5.1/(第 2/6 页)2010-9-3 17:29:35
Lua 5.1 Reference Manual - contentsr
4.1 - Functions and Types
●
5 - Standard Libraries
r
5.1 - Basic Functions
r
5.2 - Coroutine Manipulation
r
5.3 - Modules
r
5.4 - String Manipulation
■
5.4.1 - Patterns
r
5.5 - Table Manipulation
r
5.6 - Mathematical Functions
r
5.7 - Input and Output Facilities
r
5.8 - Operating System Facilities
r
5.9 - The Debug Library
6 - Lua Stand-alone
7 - Incompatibilities with the Previous Version
r
7.1 - Changes in the Language
r
7.2 - Changes in the Libraries
r
7.3 - Changes in the API
8 - The Complete Syntax of Lua
●
●
●
IndexLua functions_G
_VERSION
assert
collectgarbage
dofile
error
getfenv
getmetatable
ipairs
load
file:close
file:flush
file:lines
file:read
file:seek
file:setvbuf
file:write
C APIlua_Alloc
lua_CFunction
lua_Debug
lua_Hook
lua_Integer
lua_Number
lua_Reader
lua_State
lua_Writer
auxiliary libraryluaL_Buffer
luaL_Reg
luaL_addchar
luaL_addlstring
luaL_addsize
luaL_addstring
luaL_addvalue
luaL_argcheck
luaL_argerror
/manual/5.1/(第 3/6 页)2010-9-3 17:29:35
Lua 5.1 Reference Manual - contentsloadfile
loadstring
module
next
pairs
pcall
rawequal
rawget
rawset e
require
select
setfenv
setmetatable
tonumber
tostring
type
unpack
2
xpcall
g
v
k
10
o
al
atable
istry
alue
v
k
al
seed/manual/5.1/(第 4/6 页)2010-9-3 17:29:35lua_atpanic
lua_call
lua_checkstack
lua_close
lua_concat
lua_cpcall
lua_createtable
lua_dump
lua_equal
lua_error
lua_gc
lua_getallocf
lua_getfenv
lua_getfield
lua_getglobal
lua_gethook
lua_gethookcount
lua_gethookmask
lua_getinfo
lua_getlocal
lua_getmetatable
lua_getstack
lua_gettable
lua_gettop
lua_getupvalue
lua_insert
lua_isboolean
lua_iscfunction
lua_isfunction
lua_islightuserdata
lua_isnil
lua_isnone
lua_isnoneornil
lua_isnumber
lua_isstring
lua_istable
lua_isthread
lua_isuserdata
luaL_buffinit
luaL_callmeta
luaL_checkany
luaL_checkint
luaL_checkinteger
luaL_checklong
luaL_checklstring
luaL_checknumber
luaL_checkoption
luaL_checkstack
luaL_checkstring
luaL_checktype
luaL_checkudata
luaL_dofile
luaL_dostring
luaL_error
luaL_getmetafield
luaL_getmetatable
luaL_gsub
luaL_loadbuffer
luaL_loadfile
luaL_loadstring
luaL_newmetatable
luaL_newstate
luaL_openlibs
luaL_optint
luaL_optinteger
luaL_optlong
luaL_optlstring
luaL_optnumber
luaL_optstring
luaL_prepbuffer
luaL_pushresult
luaL_ref
luaL_register
luaL_typename
luaL_typerror
luaL_unref
Lua 5.1 Reference Manual - atable
alue
ack
me
e
ale
e
s
b
e
/manual/5.1/(第 5/6 页)2010-9-3 17:29:35lua_lessthan luaL_where
lua_load
lua_newstate
lua_newtable
lua_newthread
lua_newuserdata
lua_next
lua_objlen
lua_pcall
lua_pop
lua_pushboolean
lua_pushcclosure
lua_pushcfunction
lua_pushfstring
lua_pushinteger
lua_pushlightuserdata
lua_pushliteral
lua_pushlstring
lua_pushnil
lua_pushnumber
lua_pushstring
lua_pushthread
lua_pushvalue
lua_pushvfstring
lua_rawequal
lua_rawget
lua_rawgeti
lua_rawset
lua_rawseti
lua_register
lua_remove
lua_replace
lua_resume
lua_setallocf
lua_setfenv
lua_setfield
lua_setglobal
lua_sethook
Lua 5.1 Reference Manual -
lua_setlocal
lua_setmetatable
lua_settable
lua_settop
lua_setupvalue
lua_status
lua_toboolean
lua_tocfunction
lua_tointeger
lua_tolstring
lua_tonumber
lua_topointer
lua_tostring
lua_tothread
lua_touserdata
lua_type
lua_typename
lua_upvalueindex
lua_xmove
lua_yield
Last update: Wed Feb 24 23:17:39 BRT 2010
/manual/5.1/(第 6/6 页)2010-9-3 17:29:35
Lua 5.1 Reference Manual Lua 5.1 Reference Manual
by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
Copyright © 2006-2008 , PUC-Rio. Freely available under the terms of the Lua license.
contents · index · english · português · español
1 - IntroductionLua is an extension programming language designed to support general procedural
programming with data description facilities. It also offers good support for object-oriented
programming, functional programming, and data-driven programming. Lua is intended to be
used as a powerful, light-weight scripting language for any program that needs one. Lua is
implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++).
Being an extension language, Lua has no notion of a "main" program: it only works
embedded in a host client, called the embedding program or simply the host. This host
program can invoke functions to execute a piece of Lua code, can write and read Lua
variables, and can register C functions to be called by Lua code. Through the use of
C functions, Lua can be augmented to cope with a wide range of different domains, thus
creating customized programming languages sharing a syntactical framework. The Lua
distribution includes a sample host program called lua, which uses the Lua library to offer a
complete, stand-alone Lua interpreter.
Lua is free software, and is provided as usual with no guarantees, as stated in its license.
The implementation described in this manual is available at Lua's official web site, .
/manual/5.1/(第 1/9 页)2010-9-3 17:33:00
Lua 5.1 Reference ManualLike any other reference manual, this document is dry in places. For a discussion of the
decisions behind the design of Lua, see the technical papers available at Lua's web site.
For a detailed introduction to programming in Lua, see Roberto's book, Programming in Lua
(Second Edition).
2 - The LanguageThis section describes the lexis, the syntax, and the semantics of Lua. In other words, this
section describes which tokens are valid, how they can be combined, and what their
combinations mean.
The language constructs will be explained using the usual extended BNF notation, in which
{a} means 0 or more a's, and [a] means an optional a. Non-terminals are shown like non-terminal, keywords are shown like kword, and other terminal symbols are shown like `=´.
The complete syntax of Lua can be found in §8 at the end of this manual.
2.1 - Lexical ConventionsNames (also called identifiers) in Lua can be any string of letters, digits, and underscores,
not beginning with a digit. This coincides with the definition of names in most languages.
(The definition of letter depends on the current locale: any character considered alphabetic
by the current locale can be used in an identifier.) Identifiers are used to name variables
and table fields.
The following keywords are reserved and cannot be used as names:
and break do else elseif end false for function if in local nil not or repeat return then true until whileLua is a case-sensitive language: and is a reserved word, but And and AND are two
different, valid names. As a convention, names starting with an underscore followed by
uppercase letters (such as _VERSION) are reserved for internal global variables used by
Lua.
The following strings denote other tokens:
/manual/5.1/(第 2/9 页)2010-9-3 17:33:00
Lua 5.1 Reference Manual + - * / % ^ # == ~= <= >= < > = ( ) { } [ ] ; : , . .. ...Literal strings can be delimited by matching single or double quotes, and can contain the
following C-like escape sequences: 'a' (bell), 'b' (backspace), 'f' (form feed), 'n' (newline),
'r' (carriage return), 't' (horizontal tab), 'v' (vertical tab), '' (backslash), '"' (quotation mark
[double quote]), and ''' (apostrophe [single quote]). Moreover, a backslash followed by a
real newline results in a newline in the string. A character in a string can also be specified
by its numerical value using the escape sequence ddd, where ddd is a sequence of up to
three decimal digits. (Note that if a numerical escape is to be followed by a digit, it must be
expressed using exactly three digits.) Strings in Lua can contain any 8-bit value, including
embedded zeros, which can be specified as '0'.
Literal strings can also be defined using a long format enclosed by long brackets. We define
an opening long bracket of level n as an opening square bracket followed by n equal signs
followed by another opening square bracket. So, an opening long bracket of level 0 is
written as [[, an opening long bracket of level 1 is written as [=[, and so on. A closing long
bracket is defined similarly; for instance, a closing long bracket of level 4 is written as ]====]. A long string starts with an opening long bracket of any level and ends at the first
closing long bracket of the same level. Literals in this bracketed form can run for several
lines, do not interpret any escape sequences, and ignore long brackets of any other level.
They can contain anything except a closing bracket of the proper level.
For convenience, when the opening long bracket is immediately followed by a newline, the
newline is not included in the string. As an example, in a system using ASCII (in which 'a' is
coded as 97, newline is coded as 10, and '1' is coded as 49), the five literal strings below
denote the same string:
a = 'alon123"' a = "alon123"" a = '97lo1004923"' a = [[alo 123"]] a = [==[ alo 123"]==]A numerical constant can be written with an optional decimal part and an optional decimal
exponent. Lua also accepts integer hexadecimal constants, by prefixing them with 0x.
Examples of valid numerical constants are
/manual/5.1/(第 3/9 页)2010-9-3 17:33:00
Lua 5.1 Reference Manual 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56A comment starts with a double hyphen (--) anywhere outside a string. If the text
immediately after -- is not an opening long bracket, the comment is a short comment, which
runs until the end of the line. Otherwise, it is a long comment, which runs until the
corresponding closing long bracket. Long comments are frequently used to disable code
temporarily.
2.2 - Values and TypesLua is a dynamically typed language. This means that variables do not have types; only
values do. There are no type definitions in the language. All values carry their own type.
All values in Lua are first-class values. This means that all values can be stored in
variables, passed as arguments to other functions, and returned as results.
There are eight basic types in Lua: nil, boolean, number, string, function, userdata, thread,
and table. Nil is the type of the value nil, whose main property is to be different from any
other value; it usually represents the absence of a useful value. Boolean is the type of the
values false and true. Both nil and false make a condition false; any other value makes it
true. Number represents real (double-precision floating-point) numbers. (It is easy to build
Lua interpreters that use other internal representations for numbers, such as single-precision float or long integers; see file luaconf.h.) String represents arrays of characters.
Lua is 8-bit clean: strings can contain any 8-bit character, including embedded zeros ('0')
(see §2.1).
Lua can call (and manipulate) functions written in Lua and functions written in C (see
§2.5.8).
The type userdata is provided to allow arbitrary C data to be stored in Lua variables. This
type corresponds to a block of raw memory and has no pre-defined operations in Lua,
except assignment and identity test. However, by using metatables, the programmer can
define operations for userdata values (see §2.8). Userdata values cannot be created or
modified in Lua, only through the C API. This guarantees the integrity of data owned by the
host program.
The type thread represents independent threads of execution and it is used to implement
coroutines (see §2.11). Do not confuse Lua threads with operating-system threads. Lua
supports coroutines on all systems, even those that do not support threads.
/manual/5.1/(第 4/9 页)2010-9-3 17:33:00
Lua 5.1 Reference ManualThe type table implements associative arrays, that is, arrays that can be indexed not only
with numbers, but with any value (except nil). Tables can be heterogeneous; that is, they
can contain values of all types (except nil). Tables are the sole data structuring mechanism
in Lua; they can be used to represent ordinary arrays, symbol tables, sets, records, graphs,
trees, etc. To represent records, Lua uses the field name as an index. The language
supports this representation by providing as syntactic sugar for a["name"]. There are
several convenient ways to create tables in Lua (see §2.5.7).
Like indices, the value of a table field can be of any type (except nil). In particular, because
functions are first-class values, table fields can contain functions. Thus tables can also
carry methods (see §2.5.9).
Tables, functions, threads, and (full) userdata values are objects: variables do not actually
contain these values, only references to them. Assignment, parameter passing, and
function returns always manipulate references to such values; these operations do not
imply any kind of copy.
The library function type returns a string describing the type of a given value.
2.2.1 - CoercionLua provides automatic conversion between string and number values at run time. Any
arithmetic operation applied to a string tries to convert this string to a number, following the
usual conversion rules. Conversely, whenever a number is used where a string is expected,
the number is converted to a string, in a reasonable format. For complete control over how
numbers are converted to strings, use the format function from the string library (see ).
2.3 - VariablesVariables are places that store values. There are three kinds of variables in Lua: global
variables, local variables, and table fields.
A single name can denote a global variable or a local variable (or a function's formal
parameter, which is a particular kind of local variable):
var ::= NameName denotes identifiers, as defined in §2.1.
/manual/5.1/(第 5/9 页)2010-9-3 17:33:00
Lua 5.1 Reference ManualAny variable is assumed to be global unless explicitly declared as a local (see §2.4.7).
Local variables are lexically scoped: local variables can be freely accessed by functions
defined inside their scope (see §2.6).
Before the first assignment to a variable, its value is nil.
Square brackets are used to index a table:
var ::= prefixexp `[ exp `]The meaning of accesses to global variables and table fields can be changed via
metatables. An access to an indexed variable t[i] is equivalent to a call gettable_event(t,i).
(See §2.8 for a complete description of the gettable_event function. This function is not
defined or callable in Lua. We use it here only for explanatory purposes.)
The syntax is just syntactic sugar for var["Name"]:
var ::= prefixexp `. NameAll global variables live as fields in ordinary Lua tables, called environment tables or simply
environments (see §2.9). Each function has its own reference to an environment, so that all
global variables in this function will refer to this environment table. When a function is
created, it inherits the environment from the function that created it. To get the environment
table of a Lua function, you call getfenv. To replace it, you call setfenv. (You can only
manipulate the environment of C functions through the debug library; (see §5.9).)
An access to a global variable x is equivalent to _env.x, which in turn is equivalent to
gettable_event(_env, "x")where _env is the environment of the running function. (See §2.8 for a complete description
of the gettable_event function. This function is not defined or callable in Lua. Similarly, the
_env variable is not defined in Lua. We use them here only for explanatory purposes.)
2.4 - StatementsLua supports an almost conventional set of statements, similar to those in Pascal or C. This
set includes assignments, control structures, function calls, and variable declarations.
/manual/5.1/(第 6/9 页)2010-9-3 17:33:00
版权声明:本文标题:C和C++程序员的Lua快速入门指南 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1702984794h438467.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论