Lua之基本语法及数据类型
1. 交互式编程
[root@redis_server_194 lua-5.3.0]# lua -i
Lua 5.3.0 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> print("liudehua")
liudehua
2. 脚本式编程
1. 创建一个以lua为后缀的文件,内容如下:
print("hello world")
2. 执行一下这个脚本
lua 1.lua
3. 完整的文件内容
#!/usr/local/bin/lua
print("hello world")
给文件添加执行权限,可以直接执行/root/1.lua
3. 注释
1. 单行注释
两个减号
2. 多行注释
--[[ aaa bbb ]]--
4. 关键词
| and | break | do | else |
| elseif | end | false | for |
| function | if | in | local |
| nil | not | or | repeat |
| return | then | true | until |
| while | goto |
5. 全局变量
> print(b) nil > b=10 > print(b) 10 删除一个全局变量 b = nil print(b) --> nil
6. Lua数据类型
| 数据类型 | 描述 |
|---|---|
| nil | 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 |
| boolean | 包含两个值:false和true。 |
| number | 表示双精度类型的实浮点数 |
| string | 字符串由一对双引号或单引号来表示 |
| function | 由 C 或 Lua 编写的函数 |
| userdata | 表示任意存储在变量中的C数据结构 |
| thread | 表示执行的独立线路,用于执行协同程序 |
| table | Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。 |
1. nil
nil作比较应该加上双引号"
> type(X) nil > type(X)==nil false > type(X)=="nil" true >
2. boolean
Lua 把 false 和 nil 看作是 false,其他的都为 true,数字 0 也是 true
print(type(true))
print(type(false))
print(type(nil))
if false or nil then
print("至少有一个是 true")
else
print("false 和 nil 都为 false")
end
if 0 then
print("数字 0 是 true")
else
print("数字 0 为 false")
end
结果:
boolean
boolean
nil
false 和 nil 都为 false
数字 0 是 true
3. number
print(type(2)) print(type(2.2)) print(type(0.2)) print(type(2e+1)) print(type(0.2e-1)) print(type(7.8263692594256e-06))
4. string
使用单引号或双引号表示,或者[[]]表示一块字符串
在数字字符串进行算术操作时,Lua尝试将这个数字字符串转成一个数字
> print("2" + 6)
8.0
> print("2" + "6")
8.0
> print("2 + 6")
2 + 6
> print("-2e2" * "6")
-1200.0
1. 字符串操作
1. 字符串转换为大写字母
> string.upper("agc");
AGC
2. 字符串转换为小写字母
> string.lower("DFDE")
dfde
3. 字符串替换
> string.gsub("yangjianbo","yang","liu",3);
liujianbo
完整原型:
string.gsub (s, pattern, repl [, n])
s: 原始字符串
pattern: 要查找的模式(可以是普通字符串或正则模式)
repl: 替换成的内容
n: 最多替换几次
4. 字符串的索引位置
> string.find("yangjianbo",'bo',2)
9 10
完整原型:
string.find (s, pattern [, init [, plain]])
s: 要搜索的字符串
pattern: 要匹配的模式(可以是普通字符串或lua模式串)
init: 从字符串的哪个位置开始搜索(默认1)
plain: 如果为true,则关闭模式匹配,只做普通字符串查找
5. 字符串反转
> string.reverse("yang")
gnay
6. 格式化字符串
> string.format("fdsfsdf %s",4)
fdsfsdf
| 占位符 | 说明 | 示例 |
| ----------- | --------------- | ------------------------------------------------------ |
| `%s` | 字符串 | `string.format("hello %s", "world")` → `"hello world"` |
| `%d` | 整数(十进制) | `string.format("num = %d", 42)` → `"num = 42"` |
| `%i` | 整数(十进制,和 %d 类似) | 同上 |
| `%f` | 浮点数 | `string.format("%.2f", 3.14159)` → `"3.14"` |
| `%e` / `%E` | 科学计数法 | `string.format("%e", 314159)` → `"3.141590e+05"` |
| `%x` | 十六进制(小写) | `string.format("%x", 255)` → `"ff"` |
| `%X` | 十六进制(大写) | `string.format("%X", 255)` → `"FF"` |
| `%o` | 八进制 | `string.format("%o", 9)` → `"11"` |
| `%%` | 输出 `%` 本身 | `string.format("100%%")` → `"100%"` |
7. 字符串长度
> string.len("aaa")
3
8. 复制字符串
> string.rep("dsfs",5)
dsfsdsfsdsfsdsfsdsfs
9. 链接两个字符串..
> print("sdfds".."dddd")
sdfdsdddd
2. 字符串截取
string.sub(s, i [, j])
s: 要截取的字符串
i: 截取开始位置
j: 截取结束位置,默认为-1,最后一个字符
-- 字符串
local sourcestr = "prefix--runoobgoogletaobao--suffix"
print("\n原始字符串", string.format("%q", sourcestr))
-- 截取部分,第4个到第15个
local first_sub = string.sub(sourcestr, 4, 15)
print("\n第一次截取", string.format("%q", first_sub))
-- 取字符串前缀,第1个到第8个
local second_sub = string.sub(sourcestr, 1, 8)
print("\n第二次截取", string.format("%q", second_sub))
-- 截取最后10个
local third_sub = string.sub(sourcestr, -10)
print("\n第三次截取", string.format("%q", third_sub))
-- 索引越界,输出原始字符串
local fourth_sub = string.sub(sourcestr, -100)
print("\n第四次截取", string.format("%q", fourth_sub))
5. table
默认初始索引从1开始
最简单构造表达式{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表
a = {}
a["key"] = "value"
key = 10
a[key] = 22
a[key] = a[key] + 11
for k, v in pairs(a) do
print(k .. " : " .. v)
end
结果:
key : value
10 : 33
1. table的构造
-- 初始化表
mytable = {}
-- 指定值
mytable[1]= "Lua"
-- 移除引用
mytable = nil
-- lua 垃圾回收会释放内存
2. 例子
-- 简单的 table
mytable = {}
print("mytable 的类型是 ",type(mytable))
mytable[1]= "Lua"
mytable["wow"] = "修改前"
print("mytable 索引为 1 的元素是 ", mytable[1])
print("mytable 索引为 wow 的元素是 ", mytable["wow"])
-- alternatetable和mytable的是指同一个 table
alternatetable = mytable
print("alternatetable 索引为 1 的元素是 ", alternatetable[1])
print("mytable 索引为 wow 的元素是 ", alternatetable["wow"])
alternatetable["wow"] = "修改后"
print("mytable 索引为 wow 的元素是 ", mytable["wow"])
-- 释放变量
alternatetable = nil
print("alternatetable 是 ", alternatetable)
-- mytable 仍然可以访问
print("mytable 索引为 wow 的元素是 ", mytable["wow"])
mytable = nil
print("mytable 是 ", mytable)
3. Table操作
1. Table连接
table.concat(table,sep,start,end)
sep 分隔符
start 开始位置
end 结束位置
fruits = {"banana","orange","apple"}
-- 返回 table 连接后的字符串
print("连接后的字符串 ",table.concat(fruits))
-- 指定连接字符
print("连接后的字符串 ",table.concat(fruits,", "))
-- 指定索引来连接 table
print("连接后的字符串 ",table.concat(fruits,", ", 2,3))
结果:
连接后的字符串 bananaorangeapple
连接后的字符串 banana, orange, apple
连接后的字符串 orange, apple
2. 插入和删除
fruits = {"banana","orange","apple"}
-- 在末尾插入
table.insert(fruits,"mango")
print("索引为 4 的元素为 ",fruits[4])
-- 在索引为 2 的键处插入
table.insert(fruits,2,"grapes")
print("索引为 2 的元素为 ",fruits[2])
print("最后一个元素为 ",fruits[5])
table.remove(fruits) 移除的是最后一个元素
print("移除后最后一个元素为 ",fruits[5])
结果:
索引为 4 的元素为 mango
索引为 2 的元素为 grapes
最后一个元素为 mango
移除后最后一个元素为 nil
3. 排序
对给定的table进行升序排序
fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in ipairs(fruits) do
print(k,v)
end
要查看table的所有键值,需要自己遍历
table.sort(fruits)
print("排序后")
for k,v in ipairs(fruits) do
print(k,v)
end
结果:
排序前
1 banana
2 orange
3 apple
4 grapes
排序后
1 apple
2 banana
3 grapes
4 orange
4. Table最大值
function table_maxn(t)
local mn=nil;
for k, v in pairs(t) do
if(mn==nil) then
mn=v
end
if mn < v then
mn = v
end
end
return mn
end
tbl = {[1] = 2, [2] = 6, [3] = 34, [26] =5}
print("tbl 最大值:", table_maxn(tbl))
print("tbl 长度 ", #tbl)
结果:
tbl 最大值: 34
tbl 长度 3
6. function
函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里
function factorial1(n)
if n == 0 then
return 1
else
return n * factorial1(n - 1)
end
end
print(factorial1(5))
factorial2 = factorial1
print(factorial2(5))
结果:
120
120
function testFun(tab,fun)
for k ,v in pairs(tab) do
print(fun(k,v));
end
end
tab={key1="val1",key2="val2"};
testFun(tab,
function(key,val)--匿名函数
return key.."="..val;
end
);
结果:
key1 = val1
key2 = val2
7. thread
在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。
线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。
8. userdata
userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。
9. 数组
数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。
1. 一维数组
array = {"Lua", "Tutorial"}
for i= 0, 2 do
print(array[i])
end
2. 多维数组
-- 初始化数组
array = {}
for i=1,3 do
array[i] = {}
for j=1,3 do
array[i][j] = i*j
end
end
-- 访问数组
for i=1,3 do
for j=1,3 do
print(array[i][j])
end
end

浙公网安备 33010602011771号