lua语言快速入门

1. Lua快速入门

1.1 数据类型

Lua 中的数据类型不多,可以通过 type 函数来返回一个值的类型

print(type(print))
print(type(true))
print(type(360.0))
print(type({}))
print(type(nil))
--function
--boolean
--number
--table
--nil

1.1.2 字符串

在 Lua 中,字符串是不可变的值,如果要修改某个字符串,就等于创建了一个新的字符串。这种做法显然有利有弊:好处是即使同一个字符串出现了很多次,在内存中也只有一份;但劣势也很明显,如果想修改、拼接字符串,会额外地创建很多不必要的字符串。

下面这段代码来说明这个弊端。把 1 到 10 这些数字当作字符串拼接起来,在 Lua 中,使用两个点号来表示字符串的相加

local s = ""
for i = 1, 10 do
    s = s .. tostring(i)
end print(s)

这里循环了 10 次,但只有最后一次是想要的,而中间新建的 9 个字符串都是无用的。它们不仅占用了额外的空间,也消耗了不必要的 CPU 运算。

另外,在 Lua 中,有三种方式可以表达一个字符串:单引号、双引号,以及长括号([[]])。
长括号中的字符串不会做任何的转义处理,如果字符串中包括了长括号本身,则在长括号中间增加一个或者多个 = 符号

print([[string has \n and \r]])
-- string has \n and \r
print([=[string has a [[]].]=])
-- string has a [[]].

1.1.3 布尔值

在 Lua 中,只有 nil 和 false 为假,其他都为真,包括 0 和空字符串也为真。

local a = 0
if a then
    print("true")
end
a = ""
if a then
    print("true")
end

这种判断方式和很多常见的开发语言并不一致,所以,为了避免在这种问题上出错,可以显式地写明比较的对象,比如下面这样:

local a = 0
if a == false then
    print("true")
end

1.1.4 数字

Lua 的 number 类型,是用双精度浮点数来实现的。值得一提的是,LuaJIT 支持 dual-number(双数)模式,也就是说, LuaJIT 会根据上下文来用整型来存储整数,而用双精度浮点数来存放浮点数。

此外,LuaJIT 还支持长长整型的大整数,比如下面的例子
resty(OpenResty命令)


$ resty -e 'print(9223372036854775807LL - 1)'
9223372036854775806LL

1.1.5 函数

可以把函数存放在一个变量中,也可以当作另外一个函数的入参和出参
比如,下面两个函数的声明是完全等价的:

function foo()
 end

foo = function ()
 end

1.1.6 table

table 是 Lua 中唯一的数据结构

local color = { first = "red" }
print(color["first"])
--red

1.1.7 空值

在 Lua 中,空值就是 nil。如果定义了一个变量,但没有赋值,它的默认值就是 nil:

local a
print(type(a))
--nil

1.2 常用标准库

Lua 比较小巧,内置的标准库并不多

1.2.1 string 库

字符串操作是最常用到的,也是坑最多的地方。Lua 的正则独树一帜,不符合 PCRE 的规范。

其中 string.byte(s [, i [, j ]]),是比较常用到的一个 string 库函数,它返回字符 s[i]、s[i + 1]、s[i + 2]、······、s[j] 所对应的 ASCII 码。i 的默认值为 1,即第一个字节,j 的默认值为 i。

print(string.byte("abc", 1, 3))
print(string.byte("abc", 3)) -- 缺少第三个参数,第三个参数默认与第二个相同,此时为 3
print(string.byte("abc"))    -- 缺少第二个和第三个参数,此时这两个参数都默认为 1
--97 98 99
--99
--97
1.2.2 table 库

table.concat一般用在字符串拼接的场景下,比如下面这个例子。它可以避免生成很多无用的字符串。

local a = {"A", "b", "C"}
print(table.concat(a))

1.2.3 math 库

Lua math 库由一组标准的数学函数构成。数学库的引入,既丰富了 Lua 编程语言的功能,同时也方便了程序的编写。

比如下面的这段代码,它可以在指定的范围内,随机地生成两个数字。

math.randomseed(os.time())
print(math.random())
print(math.random(100))

1.3 虚变量

Lua 提供了一个虚变量(dummy variable)的概念,以一个下划线来命名,用来表示丢弃不需要的数值,仅仅起到占位的作用。

下面以 string.find 这个标准库函数为例,来看虚变量的用法。这个标准库函数会返回两个值,分别代表开始和结束的下标。

如果只需要获取开始的下标,那么很简单,只声明一个变量来接收 string.find 的返回值即可:

local start = string.find("hello", "he") 
print(start)
--1

但如果只想获取结束的下标,那就必须使用虚变量了:

local _, end_pos = string.find("hello", "he")
print(end_pos)
--2

除了在返回值里使用,虚变量还经常用于循环中,比如下面这个例子:

for _, v in ipairs({ 4, 5, 6 }) do
    print(v)
end
--4
--5
--6

2. Lua 语言比较特别的几个地方

2.1 Lua 的下标从 1 开始

t={100};
print(type(t[0]))
print(type(t[1]))
--nil
--number

下标0打印出来是空值

2.2 使用 … 来拼接字符串

和大部分语言使用 + 不同,Lua 中使用两个点号来拼接字符串:

print('hello' .. ', world')

2.3 只有 table 这一种数据结构

Lua 中只有一种数据结构,那就是 table,它里面可以包括数组和哈希表:

local color = {first = "red", "blue", third = "green", "yellow"}
print(color["first"])                 --> output: red
print(color[1])                         --> output: blue
print(color["third"])                --> output: green
print(color[2])                         --> output: yellow
print(color[3])                         --> output: nil

如果不显式地用_键值对_的方式赋值,table 就会默认用数字作为下标,从 1 开始。所以 color[1] 就是 blue。

另外,想在 table 中获取到正确长度,也是一件不容易的事情

local t1 = { 1, 2, 3 }
print("Test1 " .. table.getn(t1))

local t2 = { 1, a = 2, 3 }
print("Test2 " .. table.getn(t2))

local t3 = { 1, nil }
print("Test3 " .. table.getn(t3))
--Test1 3
--Test2 2
--Test3 1

想要在 Lua 中获取 table 长度,必须注意到,只有在 table 是 ‘序列’ 的时候,才能返回正确的值。

那什么是序列呢?首先序列是数组(array)的子集,也就是说,table 中的元素都可以用正整数下标访问到,不存在键值对的情况。对应到上面的代码中,除了 t2 外,其他的 table 都是 array。

其次,序列中不包含空洞(hole),即 nil。综合这两点来看,上面的 table 中, t1 是一个序列,而 t3 是 array,却不是序列(sequence)。

2.4 默认是全局变量

在 Lua 中声明变量时,前面都要加上 local

local s = 'hello'

这是因为在 Lua 中,变量默认是全局的,会被放到名为 _G 的 table 中。不加 local 的变量会在全局表中查找,这是昂贵的操作。如果再加上一些变量名的拼写错误,就会造成难以定位的 bug。

所以,强烈建议总是使用 local 来声明变量,即使在 require module 的时候也是一样:

-- Recommended 
local xxx = require('xxx')
-- Avoid
require('xxx')
Lua 教程 lua Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组于 1993 年开发的,该小组成员有:Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo。 设计目的 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua 特性 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。 其它特性: 支持面向过程(procedure-oriented)编程和函数式编程(functional programming); 自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象; 语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持; 通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。 Lua 应用场景 游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小泓哥

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值