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')
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
lua中文教程,原名:programming in lua 目录 版权声明..............i 译序..i 目录iii 第一篇语言.......1 第0章序言.......1 0.1 序言..........1 0.2 Lua的使用者................2 0.3 Lua的相关资源............3 0.4 本书的体例.................3 0.5 关于本书...3 0.6 感谢..........4 第1章起点.......5 1.1 Chunks.......5 1.2 全局变量...7 1.3 词法约定...7 1.4 命令行方式.................7 第2章类型和值9 2.1 Nil..............9 2.2 Booleans....9 2.3 Numbers...10 2.4 Strings......10 2.5 Functions.12 2.6 Userdata and Threads.12 第3章表达式..13 3.1 算术运算符...............13 3.2 关系运算符...............13 3.3 逻辑运算符...............13 3.4 连接运算符...............14 3.5 优先级.....15 3.6表的构造..15 第4章基本语法................18 4.1 赋值语句.18 4.2 局部变量与代码块(block)......19 4.3 控制结构语句...........20 Programming in Lua iv Copyright ® 2005, Translation Team, www.luachina.net 4.4 break和return语句......23 第5章函数......24 5.1 返回多个结果值.......25 5.2可变参数..27 5.3 命名参数.28 第6章再论函数................30 6.1 闭包........32 6.2 非全局函数...............34 6.3 正确的尾调用(Proper Tail Calls)...36 第7章迭代器与泛型for....40 7.1 迭代器与闭包...........40 7.2 范性for的语义...........42 7.3 无状态的迭代器.......43 7.4 多状态的迭代器.......44 7.5 真正的迭代器...........45 第8章编译·运行·调试47 8.1 require函数.................49 8.2 C Packages.................50 8.3 错误........51 8.4 异常和错误处理.......52 8.5 错误信息和回跟踪(Tracebacks)....53 第9章协同程序................56 9.1 协同的基础...............56 9.2 管道和过滤器...........58 9.3 用作迭代器的协同...61 9.4 非抢占式多线程.......63 第10章完整示例..............68 10.1 Lua作为数据描述语言使用........68 10.2 马尔可夫链算法.....71 第二篇 tables与objects........75 第11章数据结构..............76 11.1 数组......76 11.2 阵和多维数组.........77 11.3 链表......78 11.4 队列和双端队列.....78 11.5 集合和包.................80 11.6 字符串缓冲.............80 第12章数据文件与持久化..................84 12.1 序列化...86 Programming in Lua v Copyright ® 2005, Translation Team, www.luachina.net 第13章 Metatables and Metamethods...92 13.1 算术运算的Metamethods............92 13.2 关系运算的Metamethods............95 13.3 库定义的Metamethods................96 13.4 表相关的Metamethods................97 第14章环境..103 14.1 使用动态名字访问全局变量...103 14.2声明全局变量........104 14.3 非全局的环境.......106 第15章 Packages.............109 15.1 基本方法...............109 15.2 私有成员(Privacy)................111 15.3 包与文件................112 15.4 使用全局表............113 15.5 其他一些技巧(Other Facilities)...115 第16章面向对象程序设计.................118 16.1 类.........119 16.2 继承.....121 16.3 多重继承...............122 16.4 私有性(privacy)...................125 16.5 Single-Method的对象实现方法127 第17章 Weak表...............128 17.1 记忆函数...............130 17.2 关联对象属性.......131 17.3 重述带有默认值的表...............132 第三篇标准库134 第18章数学库................135 第19章 Table库...............136 19.1数组大小................136 19.2 插入/删除..............137 19.3 排序.....137 第20章 String库..............140 20.1 模式匹配函数.......141 20.2 模式.....143 20.3 捕获(Captures).146 20.4 转换的技巧(Tricks of the Trade)151 第21章 IO库..157 21.1 简单I/O模式..........157 21.2 完全I/O 模式........160 Programming in Lua vi Copyright ® 2005, Translation Team, www.luachina.net 第22章操作系统库........165 22.1 Date和Time............165 22.2 其它的系统调用...167 第23章 Debug库..............169 23.1 自省(Introspective)..............169 23.2 Hooks...173 23.3 Profiles.174 第四篇 C API..177 第24章 C API纵览..........178 24.1 第一个示例程序...179 24.2 堆栈.....181 24.3 C API的错误处理..186 第25章扩展你的程序....188 25.1 表操作.189 25.2 调用Lua函数.........193 25.3 通用的函数调用...195 第26章调用C函数..........198 26.1 C 函数..198 26.2 C 函数库................200 第27章撰写C函数的技巧..................203 27.1 数组操作...............203 27.2 字符串处理...........204 27.3 在C函数中保存状态.................207 第28章 User-Defined Types in C........212 28.1 Userdata.................212 28.2 Metatables..............215 28.3 访问面向对象的数据...............217 28.4 访问数组...............219 28.5 Light Userdata........220 第29章资源管理............222 29.1 目录迭代器...........222 29.2 XML解析...............225

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lovelife110

你的鼓励是我创作的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值