My Old Doc#
Note
这是我以前写的文档, 还没想好怎么将其重新组织放到这个项目中.
本文主要参考自官方文档中的 Basic Concepts 一章.
Lua 中一共有这么 8 种基本数据类型:
nil: 类似于 None
boolean: true 和 false
number: 整数和浮点都是这个
string
function: 函数也是一个数据类型
userdata
thread
table: 万能数据结构, 即是列表, 也是字典, 还是面向对象的类
number_plus_minus_multiply_divide.lua
1#!/usr/bin/env lua
2
3a = 2
4b = 6
5c = 9
6
7print(string.format("a = %s", a))
8print(string.format("b = %s", a))
9print(string.format("c = %s", a))
10
11print(string.format("a + b = %s", a + b))
12print(string.format("a - b = %s", a + b))
13print(string.format("a * b = %s", a * b))
14print(string.format("a / b = %s", a / b))
15print(string.format("b / a = %s", b / a))
16print(string.format("c / a = %s", c / a))
[16]:
import subprocess
subprocess.run(["lua", "number_plus_minus_multiply_divide.lua"]);
a = 2
b = 2
c = 2
a + b = 8
a - b = 8
a * b = 12
a / b = 0.33333333333333
b / a = 3.0
c / a = 4.5
String#
字符串拼接#
两个点 .. 是字符串拼接. 相当于 Python 中的 s = "b" + s.
string_01_concatenate.lua
1#!/usr/bin/env lua
2
3s = "a"
4print(string.format("s = %s", s))
5s = "b" .. s
6print(string.format("s = %s", s))
7s = "d" .. "c" .. s
8print(string.format("s = %s", s))
9s = "e"..s
10print(string.format("s = %s", s))
[17]:
subprocess.run(["lua", "string_01_concatenate.lua"]);
s = a
s = ba
s = dcba
s = edcba
Function#
在 Lua 中定义函数非常简单, 其中 function, return, end 是关键字.
function func_name(arg1, arg2)
...
return result
end
定义函数#
第一个例子, 函数里面可以有参数, Lua 是动态语言, 参数是没有类型的. 如果一个参数被定义了, 但是却没有被赋值, 那么它的默认值是 nil.
function_01_define_a_func.lua
1#!/usr/bin/env lua
2
3function func(msg)
4 print(string.format("msg = %s", msg))
5 return "success"
6end
7
8res = func("hello alice")
9print(string.format("res = %s", res))
10
11func()
[18]:
subprocess.run(["lua", "function_01_define_a_func.lua"]);
msg = hello alice
res = success
msg = nil
定义多个参数#
function_02_multiple_argument.lua
1#!/usr/bin/env lua
2
3function func(msg1, msg2)
4 print(string.format("msg1 = %s", msg1))
5 print(string.format("msg2 = %s", msg2))
6 return "success"
7end
8
9func("hello alice", "hello bob")
[19]:
subprocess.run(["lua", "function_02_multiple_argument.lua"]);
msg1 = hello alice
msg2 = hello bob
定义可变长度的参数#
这里明确两个定义:
形参 Formal parameter, 定义的形式参数, 可以是任何值
实参 Actual parameter, 实际传入的参数, 是一个确定值
例如下面的 a 就是形参, 1 就是实参.
function func(a)
...
end
func(1)
下面的例子中我们用 ... 来表示该函数可以接受数量不同的实参. 当这个函数被调用时, 它的所有参数都会被收集到一起. 我们定义了个临时变量 args, 它是个 table, 然后我们就可以用 ipairs 函数遍历里面的元素了, 当然我们对 index 不感兴趣, 只对 value 该兴趣, 所以可以用 _ 语法 (和 Python 一样) 来忽略 index.
function_03_any_number_arg.lua
1#!/usr/bin/env lua
2
3-- Ref: https://www.runoob.com/lua/lua-functions.html
4
5function func(...)
6 local args = {...}
7 for _, arg in ipairs(args) do
8 print(arg)
9 end
10end
11
12func("alice", "bob")
[20]:
subprocess.run(["lua", "function_03_any_number_arg.lua"]);
alice
bob
定义 Key Value 风格的参数#
在 Lua 中给函数传递参数都是 positioned, 也就是只按照位置顺序传递参数. 如果你记不住这些参数的位置, 想要用 key value 的方式调用函数, 那么你只能将函数变为只有一个参数的形式, 而且这个参数是一个 table, 然后在函数内部都用 arg.key 的形式调用这些值即可.
function_04_key_value_arg.lua
1#!/usr/bin/env lua
2
3function add_two(arg)
4 return arg.a + arg.b
5end
6
7print(add_two({a=1, b=2}))
[21]:
subprocess.run(["lua", "function_04_key_value_arg.lua"]);
3
Table#
Lua 中有且只有一个数据结构 Table. 它即是链表, 也是哈希表, 还能实现模块, 面向对象等功能.
Table as Dict#
我们这里用 Python 中的 dict 来类比, 看看把 Table 当哈希表用是什么感觉.
table_as_dict.lua
1#!/usr/bin/env lua
2
3local t = {
4 a = 1,
5 b = 2,
6}
7
8print("--- access value from key ")
9print(string.format("t[\"a\"] = %s", t["a"]))
10
11print("--- iterate key value pair:")
12for k, v in pairs(t) do
13 print(string.format("key = %s, value = %s", k, v))
14end
15
16print("--- iterate key only pair:")
17for k, _ in pairs(t) do
18 print(string.format("key = %s", k))
19end
20
21print("--- iterate value only pair:")
22for _, v in pairs(t) do
23 print(string.format("value = %s", v))
24end
25
26print("--- check if table has certain key")
27print(string.format("table has key \"b\": %s", t["b"] ~= nil))
28print(string.format("table has key \"c\": %s", t["c"] ~= nil))
29
30print("--- assign key value pair")
31t["b"] = 20
32t["c"] = 30
33print(string.format("t[\"b\"] = %s, t[\"c\"] = %s", t["b"], t["c"]))
34
35print("--- delete key value pair")
36t["a"] = nil
37for k, v in pairs(t) do
38 print(string.format("key = %s, value = %s", k, v))
39end
40
41print("--- get number of pairs in table")
42function get_table_length(t)
43 local count = 0
44 for _ in pairs(t) do
45 count = count + 1
46 end
47 return count
48end
49print(string.format("%s", get_table_length(t)))
[22]:
subprocess.run(["lua", "table_as_dict.lua"]);
--- access value from key
t["a"] = 1
--- iterate key value pair:
key = a, value = 1
key = b, value = 2
--- iterate key only pair:
key = a
key = b
--- iterate value only pair:
value = 1
value = 2
--- check if table has certain key
table has key "b": true
table has key "c": false
--- assign key value pair
t["b"] = 20, t["c"] = 30
--- delete key value pair
key = c, value = 30
key = b, value = 20
--- get number of pairs in table
2
Table as List#
我们这里用 Python 中的 list 来类比, 看看把 Table 当列表用是什么感觉.
table_as_list.lua
#!/usr/bin/env lua
local t = {
[1] = "a",
[2] = "b",
[3] = "c",
[4] = "d",
[5] = "e",
}
print("--- get element by index, lua index start from 1")
print(string.format("t[1] = %s", t[1]))
print(string.format("t[2] = %s", t[2]))
print("--- get the last item in the list")
print(t[#t])
print("--- get the second last item in the list")
print(t[#t - 1])
print("--- iterate a list")
for i, v in ipairs(t) do
print(string.format("ind = %s, value = %s", i, v))
end
print("--- iterate the slice of the list")
for i, v in ipairs(t) do
if 2 <= i and i <= 4 then
print(string.format("ind = %s, value = %s", i, v))
end
end
print("--- append to the end")
table.insert(t, "f")
print(t[6])
print("--- remove the last element end")
table.remove(t)
print(t[6])
print(t[5])
[23]:
subprocess.run(["lua", "table_as_list.lua"]);
--- get element by index, lua index start from 1
t[1] = a
t[2] = b
--- get the last item in the list
e
--- get the second last item in the list
d
--- iterate a list
ind = 1, value = a
ind = 2, value = b
ind = 3, value = c
ind = 4, value = d
ind = 5, value = e
--- iterate the slice of the list
ind = 2, value = b
ind = 3, value = c
ind = 4, value = d
--- append to the end
f
--- remove the last element end
nil
e
Table as Class#
在 Lua 中通常用 Table 模拟面向对象. 你直接定一个 Table. 然后它的属性可以是值, 类似于 Python 中的 property. 它的属性还可以是 function, 类似于 Python 中的 method.
oop_basic.lua
#!/usr/bin/env lua
local Rectangle = {
width = 0,
height = 0,
}
--[[
这里的 Rectangle:new 是一种语法糖, 它可以省略第一个参数 self.
--]]
function Rectangle:new(arg)
rect = {}
setmetatable(rect, self)
self.__index = self
rect.width = arg.width or 0
rect.height = arg.height or 0
return rect
end
function Rectangle:area()
return self.width * self.height
end
print("run: Rectangle:new({width=3, height=4})")
rect1 = Rectangle:new({width=3, height=4})
print(string.format("rect1.width = %s", rect1.width))
print(string.format("rect1:area() = %s", rect1:area()))
Reference:
[24]:
subprocess.run(["lua", "oop_basic.lua"]);
run: Rectangle:new({width=3, height=4})
rect1.width = 3
rect1:area() = 12
Logic Flow#
If Else#
logic_flow_if_else.lua
#!/usr/bin/env lua
-- local value = 45
-- local value = 65
local value = 85
if value <= 50 then
print(string.format("%d <= 50", value))
elseif value <= 70 then
print(string.format("50 < %d <= 70", value))
else
print(string.format("%d > 100", value))
end
[25]:
subprocess.run(["lua", "logic_flow_if_else.lua"]);
85 > 100
While#
logic_flow_while.lua
#!/usr/bin/env lua
local i = 1
while i <= 5 do
print(i)
i = i + 1
end
[26]:
subprocess.run(["lua", "logic_flow_while.lua"]);
1
2
3
4
5
[ ]: