Lua语言中的“惊喜”

Lua在有些地方没有采用其他语言(尤其是C)的约定俗成,所以经常给程序编写者带来惊喜(surprise, “gotcha”)。根据我的经验,整理如下:

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

分享