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

print

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


本文标签: 函数 线程 对象 定义 读者