Lua 5.3 参考手册 (1)
本文主要来自于Lua 5.3 Reference Manual, 参考了中文翻译, 本人摘要整理.
1 - Introduction
Lua is an extension programming language designed to support general procedural programming with data description facilities. Lua also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, lightweight, embeddable scripting language for any program that needs one. Lua is implemented as a library, written in clean C, the common subset of Standard C and C++.
As 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. The 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, standalone Lua interpreter, for interactive or batch use.
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, www.lua.org.
Like 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.
2 - Basic Concepts
这一节主要介绍了lua的基本概念
2.1 - Values and Types
Lua是一种动态类型语言(dynamically typed language). 这意味着变量(variable)是没有类型属性的, 只有值(value)具有类型属性. 在Lua中没有类型定义这一说, 所有的值自己带有类型.
value在Lua中是一等公民. 所有的values都可以存到variables中, 或者作为一个参数传递到函数中, 或者作为返回结果.
Lua中共有八种类型: nil
, boolean
, number
, string
, function
, userdata
, thread
, 和table
. 下面一一简单介绍:
nil
类型对应只有一个value, nil
, 它的类型属性和其他value是不同的; 它通常代表缺少一个有用的value.
boolean
类型对应两个value, false
以及true
. nil
和false
两个值都能够使条件判断为假; 任何其他值为真.
number
类型代表了整形数(integer numbers)和浮点数(floating-point). Lua在使用这两种代表数的时候需要显示的申明(类似C中的’f’和’l’这种吧), 但是他能够根据需要在这两种数之间自动转化(见 Section3.4.3). 因此程序员往往忽略其间的差别, 假定对每种数有足够的控制 (这是有理由的, 因为采用了64bit代表数, 特么太大了好吗). 标准的Lua使用64-bit 整形数和双精度浮点数, 但你同样可以在编译Lua的时候选择使用32-bit的整形数和单精度浮点数. 这对于某些微处理器或者嵌入式系统是attractive的. (参见源文件luaconf.h
中的宏LUA_32BITS
)
string
类型代表了不可变的字节序列. Lua是8-bit友好的, string可以包含任意8-bit的值, 包括embedded zeros (‘\0’). Lua同样是编码无关的; 它对string的内容不做任何假设.
Lua可以调用(或者操作)Lua函数或者C函数(见Section 3.4.10). 两者都可以由function
类型代表.
userdata
类型用来将C语言中的任意数据存储在Lua variable中. userdata
的值代表了一块原始的内存块. 有两种userdata
: full userdata
, 指由Lua管理一块内存的对象; 以及light userdata
, 则指一个简单的 C 指针. 在Lua中, Userdata
没有预先定义的操作, 除了赋值以及identity test. 通过使用metatables
, 程序员可以为full userdata values
定义操作(见Section 2.4). userdata
的值无法通过Lua产生或者修改, 只能通过C API, 从而保证了与主机程序的数据一致性.
thread
类型代表了独立的执行线程, 通常用来实现协同程序的(coroutines 见 Section2.6). Lua线程与操作系统线程没有关系. Lua在所有系统上支持协同线程, 即便是那些本生不支持线程的系统.
table
类型实现了关联数组(associative arrys), 也即, 数组能够不仅使用数字作为下标, 而且可以使用除了nil
和NaN
(Not a Number is a special value used to represent undefined or unrepresentable numerical results, such as 0/0.)之外的任意Lua值. table
甚至可以是”异构的”, 就是说它能够包含所有类型的值(除了nil
). 任何key为nil
值的都不认为是table
的一部分. 相反的, 任何key拥有一个关联的nil
值的都不被认为是table
的一部分.
table
类型是Lua中唯一的建立数据结构的机制; 他们可以用来代表常用的array, sequences, symbol table, sets, records, graphs, trees 等等. 为了代表records, Lua使用field name作为索引. Lua提供了 a.name
这样的语法糖来替代 a["name"]
这种写法以方便记录这种结构的使用。在 Lua 中有多种便利的方式创建表(参见 Section3.4.9)。
我们使用术语sequence
来表示一个用 {1..n} 的正整数集做索引的表。这里的非负整数 n 被称为该序列的长度(参见Section 3.4.7).
和索引一样,table
中每个域的值也可以是任何类型。 需要特别指出的是:既然函数是一等公民之一,那么table
的域也可以是函数。 这样,表就可以携带 方法 了。 (参见 Section 3.4.11)。
索引一张表的原则遵循语言中的直接比较规则。 当且仅当 i
与 j
直接比较相等时 (即不通过metamethods
的比较), 表达式 a[i]
与 a[j]
表示了table
中相同的元素。 特别指出:一个可以完全表示为整数的浮点数和对应的整数相等 (例如:1.0 == 1)。 为了消除歧义,当一个可以完全表示为整数的浮点数做为键值时, 都会被转换为对应的整数储存。 例如,当你写 a[2.0] = true
时, 实际被插入表中的键是整数 2
。 (另一方面,2
与 "2"
是两个不同的 Lua 值, 故而它们是同一张表中的不同项。)
表(tables)、函数(functions)、线程(threads)、以及完全用户数据(full userdata)在 Lua 中被称为 对象(objects): 变量并不真的持有它们的值,而仅保存了对这些对象的引用. 赋值、参数传递、函数返回,都是针对这些值的引用进行操作, 这些操作均不会做任何形式的隐式拷贝。
库函数 type
用于以字符串形式返回给定值的类型。 (参见 Section 6.1)。
2.2 - 环境与全局环境
后面在 §3.2 以及 §3.3.3 会讨论, 引用一个叫 var 的自由名字(指在任何层级都未被声明的名字) 在句法上都被翻译为 _ENV.var 。 此外,每个被编译的 Lua 代码块都会有一个外部的局部变量叫 _ENV (参见 §3.3.2), 因此,_ENV 这个名字永远都不会成为一个代码块中的自由名字。
在转译那些自由名字时,_ENV 是否是那个外部的局部变量无所谓。 _ENV 和其它你可以使用的变量名没有区别。 这里特别指出,你可以定义一个新变量或指定一个参数叫这个名字。 当编译器在转译自由名字时所用到的 _ENV , 指的是你的程序在那个点上可见的那个名为 _ENV 的变量。 (Lua 的可见性规则参见 §3.5)
被 _ENV 用于值的那张表被称为 环境。
Lua 保有一个被称为 全局环境 特别环境。它被保存在 C 注册表 (参见 §4.5)的一个特别索引下。 在 Lua 中,全局变量 _G 被初始化为这个值。 (_G 不被内部任何地方使用。)
当 Lua 加载一个代码块,_ENV 这个上值的默认值就是这个全局环境 (参见 load)。 因此,在默认情况下,Lua 代码中提及的自由名字都指的全局环境中的相关项 (因此,它们也被称为 全局变量 )。 此外,所有的标准库都被加载入全局环境,一些函数也针对这个环境做操作。 你可以用 load (或 loadfile)加载代码块,并赋予它们不同的环境。 (在 C 里,当你加载一个代码块后,可以通过改变它的第一个上值来改变它的环境。)