Lua语言中的“惊喜”
Lua在有些地方没有采用其他语言(尤其是C)的约定俗成,所以经常给程序编写者带来惊喜(surprise, “gotcha”)。根据我的经验,整理如下:
- 不等号是
~=
,而不是!=
。
- 这是我写Lua程序时最常犯的一个笔误。只能说,几乎所有的程序语言,不等号用的都是
!=
(C家族),还有一部分用<>
(Pascal, Basic, SQL)。用~=
真的只有Lua一家。
- 未用
local
声明的变量名都是全局变量。引用未定义的全局变量,得到的值是nil
。
- 这是我写Lua程序时bug的主要来源。Lua默认措施不利于排查无意中的错误,例如变量名的拼写错误。
- 使用一个称为
strict
的模块有助于防止产生这方面的问题。
- 使用for语句循环一个表时,在
in
关键字后面必须是pairs
或者ipairs
。简单的for x in tablename
是不对的。
- 这个问题主要来自Python带来的习惯:
for x in seq:
- 如果
s = "Hello, world"
,则s[5]
的值是nil
。
- 字符串不能通过下标操作获得某个位置的字节。这是一个大的惊喜,因为给字符串做下标操作看起来在自然不过了。
- 如果想这么做,使用
s:sub(5, 5)
。(有点丑,尤其是当下标不是一个常数而是一个复杂的表达式时。)
- 表的起始下标默认是1,而不是0。
- 这主要困扰C语言的使用者。以1作为起始下标其实并不是特别别扭的事,对C语言的重度使用者除外。
- 与此相呼应,通常区间将表示为闭区间,而不是像以0作为起始下标时那样,表示为左闭右开区间。请参见Dijkstra的文章。
- (Lua 5.3) 异或运算的符号是
~
,而不是^
。
- 事实上,
^
是乘方的符号。在一些计算器以及电子试算表软件中,这个符号的确表示乘方。但是,C语言程序员仍然表示不服。(C语言没有乘方运算符。Python尊重C的约定,使用^
表示异或运算,而**
表示乘方(这个符号来自Fortran)。) - 单目运算符按位取反的符号也是
~
,这和C语言的约定一致。有趣的是,Go语言和Lua恰好相反:在Go中,异或运算和按位取反的符号都是^
,~
符号未被使用。
- 没有
continue
。
- 哈哈。