OpenResty 从入门到实战
温铭
OpenResty 软件基金会第一任主席,Apache APISIX 项目 VP
20903 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 52 讲
结束语 (1讲)
OpenResty 从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

07 | 带你快速上手 Lua

运行方式
新建文件
版本号
可执行文件
环境
math.randomseed()
math.random()
table.concat
string.byte
nil
唯一数据结构
一等公民
大整数
双数模式
双精度浮点数
真假判断
表达方式
拼接示例
不可变性
Hello World
安装
兼容性
思考题
下节课预告
初步了解
示例
用法
math 库
table 库
string 库
空值
table
函数
数字
布尔值
字符串
LuaJIT
总结
虚变量
常用标准库
数据类型
基础知识
Lua
参考文章

该思维导图由 AI 生成,仅供参考

你好,我是温铭。
在大概了解 NGINX 的基础知识后,接下来,我们就要来进一步学习 Lua 了。它是 OpenResty 中使用的编程语言,掌握它的基本语法还是很有必要的。
Lua 是一个小巧精妙的脚本语言,诞生于巴西的大学实验室,这个名字在葡萄牙语里的含义是“美丽的月亮”。从作者所在的国家来看,NGINX 诞生于俄罗斯,Lua 诞生于巴西,OpenResty 诞生于中国,这三门同样精巧的开源技术都出自金砖国家,而不是欧美,也是挺有趣的一件事。
回到 Lua 语言上。事实上,Lua 在设计之初,就把自己定位为一个简单、轻量、可嵌入的胶水语言,没有走大而全的路线。虽然你平常工作中可能没有直接编写 Lua 代码,但 Lua 的使用其实非常广泛。很多的网游,比如魔兽世界,都会采用 Lua 来编写插件;而键值数据库 Redis 则是内置了 Lua 来控制逻辑。
另一方面,虽然 Lua 自身的库比较简单,但它可以方便地调用 C 库,大量成熟的 C 代码都可以为其所用。比如在 OpenResty 中,很多时候都需要你调用 NGINX 和 OpenSSL 的 C 函数,而这都得益于 Lua 和 LuaJIT 这种方便调用 C 库的能力。
下面,我带你来快速熟悉下 Lua 的数据类型和语法,以便你后面更顺畅地学习 OpenResty。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Lua 是 OpenResty 中使用的编程语言,它是一个简单、轻量、可嵌入的胶水语言,广泛应用于网游插件、键值数据库控制逻辑等领域。本文介绍了 Lua 的基本语法和数据类型,以及在 OpenResty 环境下的运行方式。文章还提到了 Lua 中的数据类型包括字符串、布尔值、数字、函数和表,以及空值。此外,还介绍了一些常用的标准库。总的来说,本文为读者提供了快速上手 Lua 的基础知识,为后续深入学习 OpenResty 打下了基础。 在技术方面,文章重点介绍了 Lua 中的常用标准库,包括字符串操作、表操作和数学库。特别强调了在 OpenResty 环境中,建议使用 OpenResty 提供的 `ngx.re.*` 来解决正则表达式,避免使用 Lua 的 `string.*` 处理。此外,还介绍了 `table.concat` 和 `math.random()` 等函数的用法,以及虚变量的概念和应用场景。 总的来说,本文内容简洁清晰,适合初学者快速了解 Lua 的基本特点和用法,同时也为进一步学习 OpenResty 提供了基础知识。通过介绍常用标准库和特殊概念,读者可以快速掌握 Lua 在 OpenResty 中的应用,为技术实践提供了有益的指导和建议。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《OpenResty 从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(25)

  • 最新
  • 精选
  • HelloBug
    网上有种设置随机数种子的方法: math.randomseed(tostring(os.time()):reverse():sub(1, 6)) 即将时间值转换为字符串,然后将字符串倒序,然后取其前六位作为种子。之所以这样做的原因是因为当时间变化很小的时候,产生随机数的序列很相似。所以通过这种方法使得即使时间变化很小,由于reverse操作,时间的高位变成低位,低位变成高位,随机数种子的值变化会很大。 关于这种做法有以下两个问题: 1.当前执行os.time()打印的时间是1560251897,总共十位。认为函数中使用sub(1, 6)这里取前6位的中的6并不是一个固定的值,而且并没有什么意义,直接使用math.randomseed(tostring(os.time()):reverse())就能达到想要的效果。难道有其他我没有想到的原因? 2.这样的做法并不能阻止在同一秒内产生相同的随机数序列,如执行以下代码: math.randomseed(tostring(os.time()):reverse():sub(1, 6)) print(math.random()) print(math.random()) math.randomseed(tostring(os.time()):reverse():sub(1, 6)) print(math.random()) print(math.random()) 输出结果是: 0.49256881466135 0.0046852543018758 0.49256881466135 0.0046852543018758 另一种说法是对计算机的一些操作,如键盘、鼠标操作,会产生一些随机数,这些随机数叫熵。用户可以通过读取/dev/random和/dev/urandom文件来获取这些随机数。只不过读取/dev/random时,如果文件里的熵不足时会阻塞。读取/dev/urandom时,不会阻塞,但不能保证是合适的数据(熵不足时怎么处理未测试)。关于熵的还有其他相关知识,如通过操作鼠标、键盘等可以产生熵,通过cat /proc/sys/kernel/random/entropy_avail操作可以查看有多少熵可以用等。 这样的话,通过读取/dev/urandom设置随机数种子,是一种方法,但觉得这种文件读取操作,效率太低。 另外看留言里有人说通过系统调用,利用芯片电磁噪声来生成随机数。没有搜到是哪个系统调用。

    作者回复: 很详细了。如果有加密的需求,从 /dev/random 和 /dev/urandom 读取会更安全,毕竟只是 init 的时候读取一次。

    2019-06-11
    2
    24
  • HelloBug
    返回三个变量,前两个变量重复使用同一个虚变量的例子: resty -e 'local function sum(a, b) return a, b, a + b end local _, _, result = sum(1, 2) print(result)' os.time返回当前时间的秒数,如果在同一秒内设置当前时间秒数为种子,然后执行随机数生成函数,产生的随机数序列是一样的。如: resty -e 'math.randomseed(os.time()) print(math.random()) print(math.random()) math.randomseed(os.time()) print(math.random()) print(math.random())' 输出结果是: 0.71251659032569 0.36755092546457 0.71251659032569 0.36755092546457 可以看到两次产生的随机数序列相同。

    作者回复: 👍

    2019-06-11
    6
  • 明白了, os.time 是秒级别的,如果短时间运行多次会出现相同的随机数

    作者回复: 是的,没错

    2019-06-10
    5
  • 叫我图图就可以了
    种子会出现相同的,简单的做法可以用GUID或者UUID之类的做种子吧.

    作者回复: uuid 本身也是先有种子,然后通过随机数生成的。

    2019-06-10
    4
  • John
    请问一下老师,如果我在init_by_lua 中引入某个模块,不加local,作为全局变量,是不是说这个模块就可以在以后rewrite,access 等阶段直接拿来使用?这样做相比较于在各个阶段自己引入模块,是否减少了require的次数,提高了性能?

    作者回复: 不会提高性能,模块在单个 worker 中只会加载一次,和是否加了 local 无关。设置为全局变量,很容易出错,比如重名什么的。在OpenResty 中建议所有变量都 local。

    2019-06-11
    3
  • WL
    请问一下老师在for _, v in ipairs({4,5,6}) do ... 这段代码中的虚变量表示的是什么含义, 有点没太看懂.

    作者回复: 代表的就是下标,也就是 key

    2019-06-10
    1
  • 夏天的风
    请问一下windows上怎么运行resty,我看用luajit a.lua是可以成功的,用luajit -e 'print("hello")' 会报错,用resty -e 'print("hello")' 也会报同样的错误。 D:\lua>luajit -e 'print("hello")' luajit: (command line):1: unexpected symbol near ''print(hello)'' D:\lua>luajit a.lua hello world

    作者回复: 推荐在 Linux 环境运行专栏的代码,Windows 上OpenResty 自己也是功能受限的。

    2019-07-03
  • 小飞哥 ‍超級會員
    为什么我这里没有luajit? localhost: ~> whicht luajit -bash: whicht: command not found localhost: ~> which luajit localhost: ~> luajit -v -bash: luajit: command not found localhost: ~> 是否我安装有问题 localhost: /usr/local/opt/openresty> pwd /usr/local/opt/openresty localhost: /usr/local/opt/openresty> openresty -v nginx version: openresty/1.15.8.1 localhost: /usr/local/opt/openresty>

    作者回复: luajit 在 /usr/local/openresty/luajit/ 目录中,避免污染系统的 luajit

    2019-06-16
  • chengzise
    1. 用当前时间戳作为种子的,是通用做法没有什么大问题。这种方式利用的是随机数生成函数,随机数重复周期很长而已,不能算是完全随机。 大多数使用环境没什么问题。 2. 在要求严格随机数环境中,例如:加解密算法。可以使用系统提供的随机数接口,这种方式利用的是芯片电磁噪声来生成随机数。由于需要经过系统调用,理论上速度没有第一种方式快。 可以根据需要选择哪种方式。

    作者回复: 就是要有足够的熵

    2019-06-10
  • Rye
    机器名+进程ID+线程ID+毫秒时间戳做种子
    2019-06-11
    4
收起评论
显示
设置
留言
25
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部