数据类型常用操作
原创大约 7 分钟
string
-- 2个方括号[[]]的作用类似于Python或Groovy中三引号字符串的作用
-- 声明变量不需要任何类型,直接赋值就行
html = [[
<html>
<head>test.lua</head>
<body>
this is a test.lua file
</body>
</html>
]]
print(html)
-- 当字符串和数字执行算术操作时,Lua会尝试将字符串转成一个数字,不过这个字符串要是一个数字字符串才行,如果是字母的会报错
print("1" + 1)
print("1" - 1)
print("1" * 2)
print("1" / 2)
-- 下面的语句会报错
-- print("a" / 2)
-- # 用来计算字符串的长度,只要放在字符串前面就行了
print(#"hello lua")
-- 如果字符串中包含中文,#就不能用了
print("【你好,lua】的字符个数是:" .. #"你好,lua!")
print("【你好,lua】的字符个数是:" .. string.len("你好,lua!"))
-- print("【你好,lua】的字符个数是:" .. utf8.len("你好,lua!"))
-- Lua提供了很多方法来支持字符串的操作,常用的如下
print(string.upper("lua"))
print(string.lower("lua"))
print(string.reverse("lua"))
-- 找到则返回起始索引与结束索引
print(string.find("hello lua", "lua"))
print(string.format("hello %s", "lua"))
-- 下标从1开始
print(string.sub("lua is a script language", 8, -1))
-- ASCII码转换为字符
print(string.char(65))
print(string.rep("lua", 3))
table
Lua中的table
是一种非常有意思的数据类型,因为它既像Tuple
(元组),又像Map
(Key-Value
键值对)。
说它像
Tuple
(元组),是因为它可以存放不同的类型。说它像
Map
(Key-Value
键值对),是因为它可以存储不同类型的下标索引,而且互不影响。
-- 创建一个空table
table1 = {}
print("table1[1] ==> 类型:" .. type(table1[1]))
-- 有数值的表,既类似于元组,也类似于map
-- 第一套下标索引,从数字1开始
table2 = {"1", 2, 3.14, true}
print("table2[1] ==> 类型:" .. type(table2[1]) .. " ==> 值:" .. table2[1])
print("table2[2] ==> 类型:" .. type(table2[2]) .. " ==> 值:" .. table2[2])
print("table2[3] ==> 类型:" .. type(table2[3]) .. " ==> 值:" .. table2[3])
-- 后面加上 .. " ==> 值:" .. tbl2[4] 就会报错,有点莫名其妙,可能是编辑器或插件的问题,或者字符串不能和true或false值用..连接
print("table2[4] ==> 类型:" .. type(table2[4]))
-- table的长度也可以用#表示
print(#table2)
table2[5] = 1.23e+10
-- table不会固定长度大小,有新数据添加时table的长度会自动增长
print("table2[5] ==> 类型:" .. type(table2[5]) .. " ==> 值:" .. table2[5])
print(#table2)
-- 第二套下标索引,类型为字符串
table2["key1"] = 1
table2["key2"] = "2"
print("table2['key1'] ==> 类型:" .. type(table2["key1"]) .. " ==> 值:" .. table2["key1"])
print("table2['key2'] ==> 类型:" .. type(table2["key2"]) .. " ==> 值:" .. table2["key2"])
-- 当key为字符串类型时,还可以通过.操作符访问
print("table2.key1 ==> 类型:" .. type(table2.key1) .. " ==> 值:" .. table2.key1)
print("table2.key2 ==> 类型:" .. type(table2.key2) .. " ==> 值:" .. table2.key2)
-- 如果改变了key的类型,table的长度不变
print(#table2)
table2[6] = false
print(#table2)
-- 现在table1和table2是同一个东西了
table1 = table2
print("table1.key1 ==> 类型:" .. type(table1.key1) .. " ==> 值:" .. table1.key1)
print("table1.key2 ==> 类型:" .. type(table1.key2) .. " ==> 值:" .. table1.key2)
-- 修改了table1,table2也会跟着变
table1["key2"] = "修改了table1"
print("table2.key2 ==> 类型:" .. type(table2.key2) .. " ==> 值:" .. table2.key2)
-- 释放table1
table1 = nil
-- 再访问会报错
-- print("table1.key2 ==> 类型:" .. type(table1.key2) .. " ==> 值:" .. table1.key2)
-- table2不受影响
print("table2.key2 ==> 类型:" .. type(table2.key2) .. " ==> 值:" .. table2.key2)
-- table1 = {11, "22", 6.18}
table1 = {11, "22", 6.18}
-- table2第一套下标索引的值{"1", 2, 3.14, true, 1.23e+10, false}
-- table2第二套下标索引的值{1, "修改了table1"}
-- table连接
print("连接后的字符串:", table.concat(table1, "-"))
-- 插入和移除
table.insert(table1, "hello")
print("索引为4的元素是:", table1[4])
-- 在索引为2的键处插入
table.insert(table1,2,"lua")
print("现在索引为2的元素是:", table1[2])
-- 移除最后一个元素
print("最后一个元素为:", table1[5])
table.remove(table1)
print("移除后最后一个元素是:", table1[5])
-- 对table进行排序
table1 = {1, 7, 6.18, 2, 5, 3.14, 11, 9}
print("table1排序前")
for k,v in ipairs(table1) do
print(k, v)
end
table.sort(table1)
print("table1排序后")
for k,v in ipairs(table1) do
print(k, v)
end
function
function fun1(n)
return n * n
end
print(fun1(10))
print(fun1("10"))
-- 执行会报错
-- print(fun1("a"))
-- 函数还能作为参数传递,可以通过名称调用,也可以匿名调用
function fun2(k, v, func)
result = k * v
return func(result)
end
-- 通过函数名调用
print(fun2(2, 2, fun1))
-- 匿名调用
print(fun2(1, 2,
-- 匿名函数
function(k)
return k * 2;
end
))
-- 函数可以有多个返回值
function fun3(n)
return n, 2 * n, 3 * n
end
a, b, c = fun3(2)
print(a, b, c)
-- 函数也支持变长参数
-- 求平均值
function average(...)
sum = 0
-- 将参数传递给table
local arg = {...}
-- 遍历table
for k, v in ipairs(arg) do
sum = sum + v
end
-- 还可以使用select方法来遍历
print("使用select方法遍历")
for i = 1, select('#', ...) do
-- 获取每一个元素
local arg = select(i, ...);
print(arg)
end
print("总共传入 " .. #arg .. " 个参数")
-- select("#", ...) 也能获取参数个数
print("总共传入 " .. select("#", ...) .. " 个参数")
return sum / #arg
end
print(average(1, 4, 9, 12, 3.18, 11, 7))
time
Lua中的time
、difftime
和date
提供了全部的日期时间功能。
-- 返回当前的时间戳(精确到秒)
print(os.time())
-- 返回table指定日期的时间戳
-- year :必填,四位数字
-- month:必填,1~12,可以写5,也可以写05
-- day :必填,1~31,可以写9,也可以写09
-- hour :可选,0~23
-- min :可选,0~59
-- sec :可选,0~59
a = { year = 2023, month = 05, day = 31, hour = 22, min = 18, sec = 27 }
print(os.time(a))
b = { year = 2023, month = 05, day = 31 }
print(os.time(b))
-- 报错
-- c = { year = 2023, month = 05}
-- print(os.time(c))
-- time默认为美国时区,也就是1970-1-1 00:00:00表示的是美国时区,中国时区需要+8小时,1970-1-1 08:00:00
-- 中国时区
d = { year = 1970, month = 1, day = 1, hour = 8, min = 0, sec = 0 }
-- 返回0
print(os.time(d))
-- 计算时间差用os.difftime(t1, t2)
day1 = { year = 2023, month = 5, day = 30 }
t1 = os.time(day1)
day2 = { year = 2023, month = 5, day = 31 }
t2 = os.time(day2)
print("2023-05-31 - 2023-05-30 ==> " .. os.difftime(t2, t1))
print("2023-05-30 - 2023-05-31 ==> " .. os.difftime(t1, t2))
-- 格式化日期显式
-- %Y 完整的年份(例如:2023)
-- %y 两位数的年份[00 ~ 99]
-- %m 月份数[01 ~ 12]
-- %d 一个月中的第几天[01 ~ 31]
-- %H 24小时制中的小时数[00 ~ 23]
-- %I 12小时制中的小时数[01 ~ 12]
-- %M 分钟数[00 ~ 59]
-- %S 秒数[00 ~ 59]
-- %p "AM(上午)"或"PM(下午)"
-- %j 一年中的第几天[001 ~ 366]
-- %w 一星期中的第几天[0 ~ 6 = 星期天 ~ 星期六]
-- %a 一星期中天数的简写(例如:Wed)
-- %A 一星期中天数的全称(例如:Wednesday)
-- %b 月份的简写(例如:Sep)
-- %B 月份的全称(例如:September)
-- %x 日期(例如:05/31/23)
-- %X 时间(例如:22:41:38)
-- %c 日期和时间(例如:05/31/23 22:41:38)
-- %% 字符'%'
-- *t 提取一个完整时间戳中的各种信息
print(os.date("今天是:%A, in %B"))
print(os.date("现在是:%x %X"))
print(os.date("%Y-%m-%d %H:%M:%S %p"))
-- hour 22
-- min 58
-- wday 3 一周第几天,星期天为1
-- day 31
-- month 5
-- year 2023
-- sec 0
-- yday 161
-- isdst false 是否夏令时
t = os.date("*t", os.time());
for i, v in pairs(t) do
print(i, v);
end
model
Lua5.1
版本中引入了模块
(model
)管理机制,它是由变量、函数和其他元素组成的Table
。
生成模块就是返回Table
,引用模块就是引用Table
。
定义模块的Lua代码。
注意:文件中的模块名new_model
必须和文件名一致,否则会找不到模块。
-- 定义一个名为new_model的模块,其实就是一个table
new_model = {}
-- 定义模块的常量
new_model.constant = "模块的常量"
-- 定义模块的函数
function new_model.f1()
print("这是模块的公有函数f1")
end
-- 模块的私有函数
local function f2()
print("这是模块的私有函数f1")
end
-- 公共函数调用私有函数
function new_model.f3()
f2()
end
return new_model
Lua会通过环境变量LUA_PATH
来查找模块所在的位置,Lua提供了一个预定义的全局变量package.path
来保存LUA_PATH
的值,可以把它打印出来。
print(package.path)
-- 结果是:;.\?.lua;C:\softwares\lua\lua\?.lua;C:\softwares\lua\lua\?\init.lua;C:\softwares\lua\?.lua;C:\softwares\lua\?\init.lua;C:\softwares\lua\lua\?.luac
结果中的?
是一个通配符。
可以将刚才编写的new_model.lua
文件拷贝到环境变量的所在的路径中去。
也可以将new_model.lua
文件所在的路径加入到环境变量中。
require ("new_model")
print(new_model.constant)
new_model.f3()
感谢支持
更多内容,请移步《超级个体》。