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

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
J
Java Code Geeks
量子位
腾讯CDC
C
Check Point Blog
小众软件
小众软件
IT之家
IT之家
I
InfoQ
Hugging Face - Blog
Hugging Face - Blog
Stack Overflow Blog
Stack Overflow Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
博客园_首页
S
SegmentFault 最新的问题
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
aimingoo的专栏
aimingoo的专栏
P
Proofpoint News Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
T
Tailwind CSS Blog
Martin Fowler
Martin Fowler

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为例)
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开始。


相关文章