惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
Engineering at Meta
Engineering at Meta
博客园 - 司徒正美
T
Tailwind CSS Blog
F
Full Disclosure
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
IT之家
IT之家
J
Java Code Geeks
Y
Y Combinator Blog
Microsoft Security Blog
Microsoft Security Blog
B
Blog
V
V2EX
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
The Cloudflare Blog
Recent Announcements
Recent Announcements
博客园 - 【当耐特】
Google DeepMind News
Google DeepMind News
罗磊的独立博客
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog
云风的 BLOG
云风的 BLOG
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
酷 壳 – CoolShell
酷 壳 – CoolShell
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Security @ Cisco Blogs
MyScale Blog
MyScale Blog
MongoDB | Blog
MongoDB | Blog
U
Unit 42
H
Heimdal Security Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
V2EX - 技术
V2EX - 技术
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google Online Security Blog
Google Online Security Blog
N
News and Events Feed by Topic
Hacker News - Newest:
Hacker News - Newest: "LLM"
PCI Perspectives
PCI Perspectives
博客园 - 三生石上(FineUI控件)
I
InfoQ
SecWiki News
SecWiki News
N
News and Events Feed by Topic
D
DataBreaches.Net
Schneier on Security
Schneier on Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

Jiajun的技术笔记

你好,2026! TiDB 源码阅读(六):TiDB Coprocessor 源码解析 性能优化的核心思想 TiDB 源码阅读(五):索引 TiDB 源码阅读(四):AST、逻辑计划、物理计划 CockroachDB Serverless Architecture podman 无故退出 Cursor Control-L (CTRL-L) Keyboard Shortcuts in Terminal Replace docker with podman Using xmonad with xfce4 A RC script for freebsd frpc 自己动手写一个k8s controller AI 会取代你的(编程)岗位吗? 自建DERP服务器提升Tailscale连接速度(使用Nginx转发) 自动升级Docker容器 再读《程序员修炼之道-从小工到专家》 让浏览器下载文件 再读《软件随想录》/《黑客与画家》/《软技能》 HTTP 压力测试中的 Coordinated Omission 2的补码 编程语言中的 context 是什么? flutter macOS 构建出错 Flatpak 使用小记 Golang CAS 操作是怎么实现的 PostgreSQL 当MQ来使用 Clash 结合 工作VPN 的网络设计 使用 PostgreSQL 搭建 JuiceFS PostgreSQL 配置优化和日志分析 有GitHub Copilot?那就可以搭建你的ChatGPT4服务 窗口函数的使用(以PG为例) 读《为什么学生不喜欢上学》 OpenAI Prompt Engineering 摘录和总结 读《打造真正的新产品》 VueJS 总结 Linux 自动挂载 alist 提供的webdav FreeBSD 使用 vm-bhyve 安装Debian虚拟机 FreeBSD 和 Linux 网卡聚合实现提速 GPT 帮我搞定了时区转换问题 长任务系统如何处理? macOS/Linux 编译 InputLeap 使用开源软KVM - synergy-core 解决 macOS 终端hostname一直变化问题 KVM 共享 Intel 集成显卡 PromQL 备忘 读《格鲁夫给经理人的第一课》 读《打开心智》 为什么要把复杂的联表操作拆成多个单表查询? 红包系统的设计 MySQL Index Condition Pushdown Optimization Go mod 简明教程 OpenWRT 使用 Android/iOS USB 网络 搭建旁路由 Golang gRPC 错误处理 编写可维护的单元测试代码 OAuth 2 详解(六):Authorization Code Flow with PKCE OAuth 2 详解(五):Device Authorization Flow OAuth 2 详解(三):Resource Owner Password Credentials Grant OAuth 2 详解(四):Client Credentials Flow OAuth 2 详解(二):Implict Grant Flow OAuth 2 详解(一):简介及 Authorization Code 模式 ElasticSearch 学习笔记 三种git流程以及发版模型 错误处理实践 权限模型(RBAC/ABAC) OIDC(OpenID Connect) 简介 任务队列简介 PostgreSQL 操作笔记 使用Drone CI构建CI/CD系统 Golang migrate 做数据库变更管理 使用PostgreSQL做搜索引擎 Nginx 源码阅读(三): 连接池、内存池 Nginx 源码阅读(二): 请求处理 Nginx 源码阅读(一): 启动流程 Go 泛型简明教程 KVM 显卡穿透给 Windows 使用 HTTP Router 处理 Telegram Bot 按钮回调 使用反射(reflect)对结构体赋值 GIN 是如何绑定参数的 你好 2022(2021 年终总结) 用Go导入大型CSV到PostgreSQL 使用 OpenWRT 搭建软路由 使用软KVM切换器 barrier 共享键鼠 SQL 防注入及原理 使用 gomock 测试 Go 代码 gevent不是黑魔法(二): gevent 实现 gevent不是黑魔法(一): greenlet 实现 用 entgo 替代 gorm 应用内使用crontab不是那么方便 单测时要不要 mock 数据库? Sentry 自建指南 用selenium完成自动化任务 用闲置的安卓手机做垃圾电话短信过滤 推荐三个时间管理工具 一次事故反思 当JS遇到uint64:JS整数溢出问题 SQLite3 存储以及ACID原理 Redis源码阅读:pub/sub实现 Redis源码阅读:zset实现 Redis源码阅读:bitmap 位图的运算 Redis源码阅读:set是怎么做交并集运算的?
Lua Manual 阅读笔记
Jiajun Huang · 2017-08-09 · via Jiajun的技术笔记
  • 关键字:

    and break do else elseif end false for function if in local
    nil not or repeat return then true until while
    
  • Lua 中约定: 以下划线开头, 后接大写字母的为保留的全局变量. 例如 _VERSION

    > print(_VERSION)
    Lua 5.1
    
  • tokens:

    + - * / % ^ # == ~= <= >= < > =
    (  ) {  } [  ] ; : , . .. ...
    
  • 字符串可以以单引号或者双引号包围,中间可以包含c风格的转义字符串如 \t 等.

    • \a 响铃
    • \b 空格
    • \f form feed
    • \n 新的一行
    • \r 回车
    • \t 横向tab
    • \v 纵向tab
    • \\ \本身
    • \" 双引号本身
    • \' 单引号本身
    • \ 加 回车代表字符串里新的一行
  • 不转义字符可以用 [[ 的两个 [ 中间加上n个 = 来表示, 0个就是0级, n个就是 n级. 如果开括号后直接跟一个换行符, 则忽略这个换行符:

    > print('hello\n123')
    hello
    123
    > print([[hello
    >> 123]])
    hello
    123
    > print([[
    >> hello
    >> 123]])
    hello
    123
    
  • 字符串也可以用 \ 加上其ascii值来表示, 十进制,最多三位. 如 \97

  • -- 开头的是注释, 后面可以接双括号, 不过我还是喜欢每行 -- 因为vim帮我干了.

  • lua中的值有八种类型:

    • nil
    • boolean
    • number
    • string
    • function
    • userdata 用来存储裸的内存块,只能通过c API来操作,不能在lua中直接操作
    • thread 协程中的”线程”的概念,相当于Golang中的 G
    • table 是lua中的一个数据结构,既可以当数组用,又可以当哈希表用,还有 a.name 语法糖,相当于 a["name"]

type 函数返回数据的类型:

> print(type(1))
number
> print(type("hello"))
string
  • lua会在操作字符串和数字的时候自动进行类型转换,例如:

    > print(1 + "2")
    3
    

坑啊…和js一样…我很讨厌这种特性.

  • Lua有三种变量

    • 全局变量
    • 本地变量
    • table项(table fields)

var ::= Name 的形式赋值给变量, 默认全局变量, 除非加了 local 关键字, 本地变量可以被其作用域内的函数访问到. 第一次赋值前, 变量的默认值为 nil. 全局变量存储在 _env 里.

默认全局变量,又是一个坑.

  • 赋值, 赋值的时候, 如果右边比左边长, 则多余的值会被丢掉. 相反, 则用nil填充. 赋值语句首先计算出所有变量,然后才进行赋值,例如:

    i = 3
    i, a[i] = i+1, 20
    

执行完之后, a[3] 的值是20, a[4] 不受影响.

  • falsenil 是false,其他的都是true, 所以0和空字符串也是true.

  • for有两种形式, 一种像c:

    local i = 0
    
    for i = 0, 10, 2 do
    print(i)
    end
    
    $ luajit test.lua 
    0
    2
    4
    6
    8
    10
    

只能用来做算术循环.

另一种像 Python:

local names = {"hello", "world"}

for k, v in ipairs(names) do
    print(k, v)
end
$ luajit test.lua 
1	hello
2	world
  • 函数和变长参数都可以产生多值. 如果作为表达式, 那么结果会被忽略, 例如函数 调用 f() 那么其结果会被忽略. 如果作为表达式的非最后一个元素, 那么多值结果会被 省略,只剩下第一个, 如果作为最后一个元素,那么就会保留所有结果.

    function f()
    return 1, 2, 3
    end
    
    local a
    local b
    local c
    f()
    print(a, b, c)
    
    a, b, c = f(), 4, 5
    print(a, b, c)
    
    a, b, c = f()
    print(a, b, c)
    
    a, b, c = 9, 8, f()
    print(a, b, c)
    
    $ luajit t.lua 
    nil	nil	nil
    1	4	5
    1	2	3
    9	8	1
    
  • == ~= < > <= >= 总是产生布尔值. 数字和字符串比较值,对象(tables, userdata, threads, functions)比较引用值.

  • and, or, not其中 andor 支持条件短路. 所以如果第一个参数是 false 或者 nil 就返回第一个参数,否则返回第二个参数.

  • .. 连接字符串

    > print("hello" .. 1)
    hello1
    
  • length. 通过 # 号取出长度, 对字符串来说是bytes的个数,对table来说,是最后一个 非空值的index. 例如 a[1], a[2], a[3] 为1, 而 a[4] 为nil, a[5] 为2, 那么 长度为3.

    local a = {1, 2, 3, nil, 4}
    
    print(#a)
    
    $ luajit t.lua 
    3
    

坑啊,table支持空洞额…

  • 每次遇到local关键字,都会新建一个变量。如果在for循环里local的话,就会新建 循环次数个变量。

  • metatables

lua中每个值都有metatable,其中的key称为events,值称为metamethods. 每个events 的名字都是两个下划线开头,例如 __add。主要包括以下方法:

- add +
- sub -
- mul *
- div /
- mod %
- pow ^
- unm -负号
- concat .. 字符连接号
- len # 号
- eq `==`
- lt <
- le <=
- index `table[key]`
- newindex `table[key] = value`
- call

此外,thread,function和userdata这三种类型的对象还有一个table与之相关,叫做 encironment。thread的环境变量在thread内共享,userdata和c函数在c函数内共享。 非嵌套lua函数和创建的thread共享,嵌套的lua函数和嵌套的lua函数共享。

lua thread级别的envrionment table就是全局变量。可以通过 getfenvsetfenv 获取和修改。

  • coroutine 内置coroutine算是lua的一个特色了

    • coroutine.create 返回新创建的coroutine的handle
    • coroutine.resume 开始执行coroutine
    • coroutine.yield 交出执行权
    • coroutine.wrap 返回一个函数,每次调用都会执行到上一个yield的地方

      local newThread = coroutine.wrap(function()
      print("hello")
      local a = coroutine.yield()
      print(a)
      end)
      
      newThread()
      newThread("haha")
      
  • C-API和C交互的库 略过。

  • 标准库 略过。

  • lua中 x:foo() 相当于 x.foo(x),是一种语法糖。

  • lua的index从1开始。


相关文章