1 Lua语言入门

1.1 程序段

遵照惯例,写一个输出 Hello World 的程序

  print("Hello World")

将包含以上程序代码的文件保存成 .lua 为后缀的文本文件即可,此处我们保存成 hello.lua,在命令行中,进入相应的文件夹后执行以下命令:

% lua hello.lua

得到的结果为:

Hello World

除此之外,我们也可以在交互式模式( interactive mode )下运行独立解释器。当不带参数调用 lua 时,我们可以看到以下输出:

% lua
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> 

每输入一条命令都会在按下回车后立即执行,如果不是一个完整的语句则会多一个箭头:

> a =
>> 6
> = a
6

我们通过输入EOF控制符(Windows 环境下使用 Ctrl + Z)或者调用操作系统库的 exit 函数os.exit()退出交互模式。

从 5.3 版本开始,可以直接在交互模式下输入表达式,Lua 会输出表达式的值,但之前的老版本中需要在开头输入一个=,为了向下兼容,Lua 5.3 也支持这种写法。


附 1:Lua 命令行参数

lua [options] [script [args]]

options 功能 示例
-i 执行完script之后进入交互模式 lua -i test.lua
-e 直接在命令行中传入代码 lua -e "print("Hello World")"
-l 加载一个文件 lua -l test

注意在-l为参数的时候文件名不需要加.lua 否则将会报错

Lua Scripts>lua -l test.lua
lua: module 'test.lua' not found:
        no field package.preload['test.lua']
        no file '.\test\lua.lua'
        no file 'C:\Program Files (x86)\Lua\5.1\lua\test\lua.lua'
        no file 'C:\Program Files (x86)\Lua\5.1\lua\test\lua\init.lua'
        no file 'C:\Program Files (x86)\Lua\5.1\test\lua.lua'
        no file 'C:\Program Files (x86)\Lua\5.1\test\lua\init.lua'
        no file 'C:\Program Files (x86)\Lua\5.1\lua\test\lua.luac'
        no file '.\test\lua.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\test\lua.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\loadall.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\clibs\test\lua.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\clibs\loadall.dll'
        no file '.\test\lua51.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\test\lua51.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\clibs\test\lua51.dll'
        no file '.\test.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\test.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\loadall.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\clibs\test.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\clibs\loadall.dll'
        no file '.\test51.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\test51.dll'
        no file 'C:\Program Files (x86)\Lua\5.1\clibs\test51.dll'
stack traceback:
        [C]: ?
        [C]: ?

Lua Scripts>

另一种加载文件的方法就是使用dofile(),在交互模式下输入命令:

> dofile("test.lua")
Hello World
>

1.2 词法规范

Lua 语言中的标识符是由字母、数字和下划线组成的字符串(不能以数字开头),下划线加大写字母(例如:__VERSION)组成的标识符通常被Lua语言用作特殊用途,应尽量避免使用。


附 2:Lua 保留字

and  break  do  else  elseif
end  false  goto  for  function
if  in  local  nil  not
or  repeat  return  then  true
until  while

Lua 语言对大小写敏感,所以标识符使用AND并不会与and发生冲突。


Lua 中的单行注释用--,多行注释用--[[--]]包裹住,例如:

--[[
  print("Hello World")
--]]

这段代码并不会被执行,因为被注释掉了,如果想要重新启用可以再增加一个-

---[[
  print("Hello World")
--]]

一般情况下不需要使用分号来分隔语句,但是为了易读,可以在一行中出现多个语句时使用分号进行分隔。


1.3 全局变量

在 Lua 语言中,全局变量不需要声明就可以使用,使用未经初始化的全局变量也不会导致错误。当使用未初始化的全局变量时会得到nil

> = type(a)
nil
>

nil赋给全局变量时,Lua就会回收该全局变量。


1.4 类型和值

Lua 语言是一种给动态类型语言,在这种语言中没有类型定义,每个值都带有其自身的类型信息。
Lua 语言有8中基本类型:nil空、boolean布尔、number数值、string字符串、userdata用户数据、function函数、thread线程和table
使用函数type()就可以获取一个值对应的类型名称。
注意:Type()函数的返回值类型是string 所以作比较时要使用 type(1) == "number"
userdata 类型允许把任意的C语言数据保存在 Lua 语言变量中。在 Lua 语言中,用户数据类型除了赋值和相等性测试外,没有其他预定义操作。用户数据被用来表示由应用或C语言编写的库所创建的新类型。

1.4.1 nil

nil 是一种只有一个 nil 值的类型,它的主要作用就是与其他值有所区分。Lua 语言用nil来表示无效值的情况。

Boolean

Boolean 类型有两个值,truefalse,它们分别代表了真和假。在 Lua 中只有falsenil被视为假,其他都视为真,包括0和空字符串。

> if nil or false then
>> print("true")
>> else
>> print("false")
>> end
false
>

Lua 支持常见的逻辑运算符andornotandor遵循短路原则。


练习

  • 练习 1.1:运行阶乘的示例并观察,如果输入负数,程序会出现什么问题?试着修改代码来解决问题。

如果输入负数就会发生栈溢出,所以应该对输入的数据加以限制,我写的代码如下:

function fact(x)
    if(type(x) == "number") then  --首先要保证它是一个数字
        if x % 1 < 1e-6 then    --对1取余判0,保证它是一个整数
            if x == 0 or x == 1 then
                return 1
            elseif x < 0 then  --保证它是非负数
                print("expected a nonnegative number")
            else
                return x * fact(x-1)
            end
        else
            print("not a integer")
        end
    else
        print("not a number")
    end
end

print("Please enter a number")

a = io.read("*n")  --虽然这里已经限制了读取数字,但是还是会接收到键盘输入的字符

print(fact(a))

  • 练习 1.2:分别使用-l参数和dofile运行twice示例,并感受你喜欢哪种方式。

参考附1的内容

  • 练习 1.3:你是否能举出其它使用--作为注释的语言?

sql

  • 练习 1.4:以下字符串中哪些是有效的标识符?
    ___ _end End end until? nil NULL one-step

有效:___ _end End NULL
无效:end until? nil one-step
首先保留字endnil是肯定不能做标识符的,until??不能出现在标识符中,one-step中的-会被识别为减号所以不能出现在标识符中,应改用下划线。

  • 练习 1.5:表达式type(nil) == nil的值是什么?你可以直接在 Lua 中运行来得到答案,但是你能够解释原因吗?
> = type(nil) == nil
false
>

出现这种情况的原因是,type()函数的返回值是string类型,无法直接与nil类型做比较:

> = type(type(nil))
string
>

想要解决这个问题需要将nil改为"nil"

> = type(nil) == "nil"
true
>
  • 练习 1.6:除了使用函数type外,如何检查一个值是否为Boolean类型?

可以使用==来判断一个值是否为 Boolean 类型

-- isBoolean.lua

function isBoolean(x)
    if x == true or x == false then
        return true
    else
        return false
    end
end

测试数据和结果:

> = isBoolean(true)
true
> = isBoolean(false)
true
> = isBoolean(5)
false
> = isBoolean("true")
false
>
  • 练习 1.7:考虑如下的表达式:
    (x and y and (not z)) or ((not y) and x)
    其中的括号是否是必须的?你是否推荐在这个表达式中使用括号?

运算符优先级按从高到低的顺序为:
^
not -(负数)
* /
+ -
..
< > <= >= ~= ==
and
or
由此可知not的优先级比andor要高,从语法的角度说不需要加括号,但是加上括号便于阅读,所以我推荐使用括号。

  • 练习 1.8:请编写一个可以打印出脚本自身名称的程序(事先并不知道脚本自身的名称)

脚本的名称存储在arg[0]中

-- test.lua

  print(arg[0])

必须要有对应的文件才会有返回结果,不然就会报错。

你可能感兴趣的:(1 Lua语言入门)