Lua Basic¶
本文主要参考自官方文档中的 Basic Concepts 一章.
Lua 中一共有这么 8 种基本数据类型:
nil: 类似于 None
boolean: true 和 false
number: 整数和浮点都是这个
string
function: 函数也是一个数据类型
userdata
thread
table: 万能数据结构, 即是列表, 也是字典, 还是面向对象的类
#!/usr/bin/env lua
a = 2
b = 6
c = 9
print(string.format("a = %s", a))
print(string.format("b = %s", a))
print(string.format("c = %s", a))
print(string.format("a + b = %s", a + b))
print(string.format("a - b = %s", a + b))
print(string.format("a * b = %s", a * b))
print(string.format("a / b = %s", a / b))
print(string.format("b / a = %s", b / a))
print(string.format("c / a = %s", c / a))
# output
a = 2
b = 2
c = 2
a + b = 8
a * b = 12
a / b = 0.33333333333333
b / a = 3.0
c / a = 4.5
String¶
字符串拼接¶
#!/usr/bin/env lua
s = "a"
print(string.format("s = %s", s))
s = "b" .. s
print(string.format("s = %s", s))
s = "d" .. "c" .. s
print(string.format("s = %s", s))
s = "e"..s
print(string.format("s = %s", s))
两个点 ..
是字符串拼接. 相当于 Python 中的 s = "b" + s
.
# output
s = a
s = ba
s = dcba
s = edcba
Function¶
在 Lua 中定义函数非常简单, 其中 function
, return
, end
是关键字.
function func_name(arg1, arg2)
...
return result
end
定义函数¶
第一个例子, 函数里面可以有参数, Lua 是动态语言, 参数是没有类型的. 如果一个参数被定义了, 但是却没有被赋值, 那么它的默认值是 nil.
#!/usr/bin/env lua
function func(msg)
print(string.format("msg = %s", msg))
return "success"
end
res = func("hello alice")
print(string.format("res = %s", res))
func()
# output
msg = hello!
res = success
msg = nil
定义多个参数¶
#!/usr/bin/env lua
function func(msg1, msg2)
print(string.format("msg1 = %s", msg1))
print(string.format("msg2 = %s", msg2))
return "success"
end
func("hello alice", "hello bob")
# output
msg1 = hello alice
msg2 = hello bob
定义多个参数¶
#!/usr/bin/env lua
function func(msg1, msg2)
print(string.format("msg1 = %s", msg1))
print(string.format("msg2 = %s", msg2))
return "success"
end
func("hello alice", "hello bob")
# output
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.
#!/usr/bin/env lua
-- Ref: https://www.runoob.com/lua/lua-functions.html
function func(...)
local args = {...}
for _, arg in ipairs(args) do
print(arg)
end
end
func("alice", "bob")
# output
alice
bob
定义 Key Value 风格的参数¶
在 Lua 中给函数传递参数都是 positioned, 也就是只按照位置顺序传递参数. 如果你记不住这些参数的位置, 想要用 key value 的方式调用函数, 那么你只能将函数变为只有一个参数的形式, 而且这个参数是一个 table, 然后在函数内部都用 arg.key 的形式调用这些值即可.
#!/usr/bin/env lua
function add_two(arg)
return arg.a + arg.b
end
print(add_two({a=1, b=2}))
Table¶
Lua 中有且只有一个数据结构 Table. 它即是链表, 也是哈希表, 还能实现模块, 面向对象等功能.
Table as Dict¶
我们这里用 Python 中的 dict 来类比, 看看把 Table 当哈希表用是什么感觉.
#!/usr/bin/env lua
local t = {
a = 1,
b = 2,
}
print("--- access value from key ")
print(string.format("t[\"a\"] = %s", t["a"]))
print("--- iterate key value pair:")
for k, v in pairs(t) do
print(string.format("key = %s, value = %s", k, v))
end
print("--- iterate key only pair:")
for k, _ in pairs(t) do
print(string.format("key = %s", k))
end
print("--- iterate value only pair:")
for _, v in pairs(t) do
print(string.format("value = %s", v))
end
print("--- check if table has certain key")
print(string.format("table has key \"b\": %s", t["b"] ~= nil))
print(string.format("table has key \"c\": %s", t["c"] ~= nil))
print("--- assign key value pair")
t["b"] = 20
t["c"] = 30
print(string.format("t[\"b\"] = %s, t[\"c\"] = %s", t["b"], t["c"]))
print("--- delete key value pair")
t["a"] = nil
for k, v in pairs(t) do
print(string.format("key = %s, value = %s", k, v))
end
print("--- get number of pairs in table")
function get_table_length(t)
local count = 0
for _ in pairs(t) do
count = count + 1
end
return count
end
print(string.format("%s", get_table_length(t)))
# output
--- 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
key = c, value = 30
key = b, value = 20
❯ lua table_as_dict.lua
--- access value from key
t["a"] = 1
--- iterate key value pair:
key = b, value = 2
key = a, value = 1
--- iterate key only pair:
key = b
key = a
--- iterate value only pair:
value = 2
value = 1
--- 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 = b, value = 20
key = c, value = 30
--- get number of pairs in table
2
Table as List¶
我们这里用 Python 中的 list 来类比, 看看把 Table 当列表用是什么感觉.
#!/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])
#output
--- 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
Local and Global Variable¶
在 lua 中, 如果你不声明 local
就定义变量, 那么这个变量就是全局变量. 全局变量可以在函数内部被修改. 一般好的 lua 代码中所有的变量都应该定义成局部变量才能避免出 bug. 请看下面的例子:
#!/usr/bin/env lua
a = 1
function func1()
a = 2
print(string.format("inside function a = %s", a))
end
func1()
print(string.format("outside function a = %s", a))
b = 1
function func2()
local b = 2
print(string.format("inside function b = %s", b))
end
func2()
print(string.format("outside function b = %s", b))
local c = 1
function func3()
c = 2
print(string.format("inside function c = %s", c))
end
func3()
print(string.format("outside function c = %s", c))
local d = 1
function func4()
local d = 2
print(string.format("inside function d = %s", d))
end
func4()
print(string.format("outside function d = %s", d))
# output
inside function a = 2
outside function a = 2
inside function b = 2
outside function b = 1
inside function c = 2
outside function c = 2
inside function d = 2
outside function d = 1
OOP¶
#!/usr/bin/env lua
local Rectangle = {
width = 0,
height = 0,
}
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
rect1 = Rectangle:new({width=3, height=4})
print(rect1.width)
print(rect1:area())
Reference: