Lua 学习之基础篇十<Lua 常见的语法规则>
下面讲一些lua 常见的用法和规则,可以为学习理解lua带来帮助,最后附上的部分是lua的基本操作,基本包含所有常用语法语句。
1. if判断
lua把 nil 和false 视为“假”,其他都为“真”
2. 逻辑运算符 and or
lua的and or 可以用来构成三元表达式,如下:
> = 1 == 1 and 1 or 2
1
但如果是这样写,就不是你想要的结果了:
> = 1 == 1 and false or true
true
这是因为,and 运算符判定 false不成立,就继续执行了 or 运算符的结果(nil和false lua都认为为假)
如果你一定要返回 true 或 false,要这么写:
> = ( 1 == 1 and {false} or {true} )[1]
false
3. local变量声明
local var1=1,var2
以上 ,var1和var2的作用域不同,var1是所在作用域的变量,var2可能是全局变量。实际上述命令解释后为 var1 取 "1,var2" 组成的值第一个值,类似 local var1 = ...
请注意变量的声明,如果不确定,就老老实实依依赋值。
local var1
local var2=1
print(var1) --nil
print(var2) --1
print("=====")
local var3 =1,var4
print(var3) --1
print(var4) --nil
print("=====")
local var5, var6=1
print(var5) --1 ->是不是很奇怪- -、这里的var5竟然是1
print(var6) --nil
4. table是否为空
if a == {} then
结果是false,这是一个逻辑错误,实际比较table a的内存地址和一个匿名table的是否相同
正确的写法是:
if next(a) == nil then
5. 多个变量赋值
name,name = 1,2
那name等于多少呢?
实际上name值为1,可以写个小例子 a,b = 2,3,4打印就可以看到了。a=2,b=3
6. table的key规则
t[name]与t["name"], t.name
第一种和后两种是不同的,第一种会根据取name的值做key,后两种以 "name"做key。这种情况还有:
t = {[name] = 1}
t = {name = 1}
t = {["name"] = 1}
7. table的长度
取得 table 长度最常用的做法是 #table,如下:
> t = {1,2,3}
> #t
3
但 # 操作符也是有局限的,不支援数组以外的对象计算,所以要谨记
> t = { 10, n = 20, 30, 40 }
> #t
3 --长度是4,所以,要采用其他方式判定长度
另外,通过把元素设 nil 无法改变 #table 的结果(除非是数组最后一个元素);而 table.remove 则可以立即更新 #table 的结果
t ={1,2,3}
t[1]=nil
print(#t) --3
table.remove(t,1)
print(#t) --2
8. table引用问题
将一个table复制给另外一个table,修改这个新的table值会影响原来的table,但通过clone可以改变这一行为
function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
9. 函数返回值
function f123()
return 1, 2, 3
end
function f456()
return 4, 5, 6
end
print(f123()) --1 2 3
print(f456()) --4 5 6
print(f123(), f456()) -- 1 4 5 6
print(f456(),1) --4 1
如果函数不是处于列的最后一个,只返回一个值
10.浮点数问题
这是浮点数都会有的精度丢失问题,lua也有这个问题。再看下整数与浮点数的比较
> =10==10.00000000000000000
true
> =10==10.00000000000000001
true
> =10==10.00000000000000000
true
> =10==9.999999999999999999
true
所以,这边测试了一下,lua 的浮点数会精确到15位,所以在比较精确的比较之前确认好精度在进行比较
11. 冒号语法
冒号语法可以用来定义函数, 这样的话,函数会有一个隐式的形参 self。
写法如下:
function t:f (params) body end
冒号语法实际上是一种语法糖,等效于:
t.f = function (self, params) body end
local t={a=123}
function t.f1(self, p)
print(self.a, p) --self.a 访问t中a的值
end
function t:f2(p)
print(self.a, p)
end
t:f1(1)
t.f1(t,1)
t:f2(1)
t.f2(t,1)
以上几个结果都是 123 1
这里,通过冒号方式调用函数不需要加入self参数,而点号则需要。
12. 函数闭包
当一个函数内部嵌套另一个函数定义时,内部的函数体可以访问外部的函数的局部变量,这种特征我们称作词法定界。
function fn()
local i = 0
return function() -- 注意这里是返回函数的地址,不是执行
i = i + 1
return i
end
end
c1 = fn() -- 接收函数返回的地址
print(c1()) --> 1 --c1()才表示执行 ,i 此时为0
print(c1()) --> 2 --继续执行函数体 此时i =1上次执行的结果
如上,调用c1()时,fn函数明显已经返回,lua闭包闭包思想正确处理这种情况:
- 我们称i为从c1的外部局部变量(external local variable)或者upvalue。
- 简单的说,闭包是一个函数以及它的upvalues
如果我们再次调用fn,将创建一个新的局部变量i:
c2 = fn()
print(c2()) --> 1
print(c1()) --> 3
print(c2()) --> 2
13. 函数尾调用
- 尾调用是一种类似在函数结尾的goto调用。
- 当函数最后一个动作是调用另外一个函数时,我们称这种调用尾调用。
function f(x)
return g(x) -- 类似于goto g(x)函数的地址
end
- 尾调用不需要使用栈空间,因此尾调用递归的层次可以无限制的。
例如下面调用不论n为何值不会导致栈溢出。
function foo (n)
if n > 0 then return foo(n - 1) end
end
需要注意的是:必须明确什么是尾调用。
一些调用者函数调用其他函数后也没有做其他的事情但不属于尾调用。比如:
function f (x)
g(x)
return
end
上面这个例子中f在调用g后,不得不丢弃g地返回值,所以不是尾调用,同样的下面几个例子也不时尾调用:
return g(x) + 1 -- 还需+1
return x or g(x) -- 还需比较
return (g(x)) -- 还需调整为一个返回值
基础语句用法详细示例
--注释方式
--[[
多行注释
--]]
--********************变量类型********************
--lua中所有的变量 不需要申明变量类型
--lua中的所有变量 默认为全局变量 非全局前面加local
--lua中没有各种数值类型 统一都是Number类型 表示浮点数和
print("*************全局本地变量*************")
local a = 1 --局部 仅限于本文本访问 编程时 尽量都加local
print(a)
a1 = 1.5 --全局
print(a1)
--lua中只有false和nil才为假 0和空字符串为真
e = true;
print(e)
--lua中的string 可以用单引号或者双引号括起来
print("*************字符串相关*************")
b = '单引号字符串'
print(b)
c = "双引号字符串"
print(c)
--lua中字符串的换行 省略了\n换行替代符号
c = [[我是
你的
小宝贝
]]
print(c)
--字符串相关
str = "abCdefg"
print(string.upper(str))--小写转大写
print(string.lower(str))--大写转小写
print(string.reverse(str))--翻转字符串
print(string.find(str, "Cde"))--字符串索引查找
print(string.sub(str, 3))--字符串截取
print(string.rep(str, 3))--字符串重复
print(string.gsub(str, "Cd", "**"))--字符串修改
print(#str)--字符串长度
a = true
print(tostring(a));
print(string.format("我是%s,我今年%d岁了", "小宝贝", 2))--字符串长度
--lua中空的关键字时nil 相当于C#中的null
print("*************空引用*************")
d = nil
print(d)
print("*************类型获取*************")
--字符串拼接符号..
--type 类型判断
print("类型判断"..type(e))
--********************运算符********************
print("*************运算符*************")
--lua中没有自增减运算符
print("加法运算"..1+2)
print("余数运算"..9%2)
print("减法运算"..9-2)
print("乘法运算"..9*2)
print("除法运算"..9/2)
print("幂运算"..9^2)
--********************条件分支语句********************
print("*************条件分支语句*************")
a = 9
if a > 9 then
print("大于9")
elseif a >= 5 then
print("大于5")
elseif a == 3 then
print("值为3")
elseif a ~= 2 then --不等于
print("值为3")
end
--********************逻辑运算符********************
print("*************逻辑运算符*************")
a = true
b = false
if a and b then --逻辑与
print("大于9")
elseif a or b5 then --逻辑或
print("大于5")
elseif not a then -- 逻辑否
print("其它数")
end
--********************循环语句********************
print("*************循环语句*************")
--while 循环
print("*************while循环*************");
num = 0
while num < 5 do
print(num);
num = num + 1
end
--do while 循环
print("*************do while循环*************");
a = 1;
repeat
print(a);
a = a + 1
until a > 5
--for循环
print("*************for循环*************");
for i = 1,5 do --默认递增+1
print(i)
end
for i = 5,1,-1 do --递减1
print(i)
end
--********************函数********************
print("*************函数*************")
function f(x)
return x^2
end
print(f(2))
function f2(x2)
if x2 < 10 then
print("白卷")
elseif x2 < 60 then
print("分太低")
elseif x2 < 70 then
print("及格")
end
end
f2(2)
print("*************变长参数函数*************")
function ff( ... )
local arg = {...}
local total = 0
for i=1,#arg do
total = total + arg[i]
end
print(total)
end
ff(1,2,3,4,5,6)
print("*************函数嵌套*************")
function f3(x)
return function(y) return x + y end
end
a = f3(1)
print(a(2))
--********************复杂数据类型********************
print("*************复杂数据类型*************")
--所有的复杂类型都是table(表)
--数组
print("*************数组,列表*************")
--数组的存储类型可以混合,默认索引从1开始
a = {1,2,3,"12312",123123}
print(a[1])
print(a[4])
print(#a)--打印长度 从1开始计数
print("*************数组遍历*************")
for i=1,#a do
print(a[i])
end
--可以自定义索引 甚至负索引
print("*************自定义索引*************")
a = {[0]=1,2,3,[-1]=4,5}
print(a[0])
print(a[1])
print(a[-1])
print(a[2])
print(a[3])
print(#a)--打印长度 中间产生索引断裂了 会停止计数
print("*************二维数组*************")
a = {{1,2,3},{4,5,6}}
print(a[1][1])
print(a[1][2])
print(a[1][3])
print(a[2][1])
print(a[2][2])
print(a[2][3])
--迭代器遍历
print("*************ipairs迭代遍历键值*************")
a = {[0] = 1,2,[-1] = 3,4,5}
--遍历键值
for i,k in ipairs(a) do
print("ipairs遍历键"..i)
print("ipairs遍历值"..k)
end
print("*************pairs迭代遍历键值*************")
for i,k in pairs(a) do
print("pairs遍历键"..i)
print("pairs遍历值"..k)
end
print("*************迭代遍历键*************")
--遍历键
for i in pairs(a) do
print("键"..i)
end
print("*************字典*************")
a = {["1"] = 5, ["2"] = 4}
print(a["1"])
print(a["2"])
print("*************类*************")
student = {
--年龄
age = 1,
--性别
sex = 0,
--unity成绩
unity = 90,
--成长行为
Up = function(self)
print("我",self.age)
self.age = self.age + 1
print("我成长了"..self.age)
end,
--上课行为
Learn = function( )
print("学习")
end
}
student.Learn()
student.Up(student)
print("F-->",student.age)
student:Up()
student:Up()
--student.Learn()
student.age = 2
print(student.age)
print("*************特殊用法*************")
a,b,c = 1,2,3,4 --4会被忽略
print(a)
print(b)
print(c)
a,b,c = 1,2 --c会变为nil
print(a)
print(b)
print(c)
--多个返回值
function Test()
return 10,20,30,40
end
a,b,c = Test()
print(a)
print(b)
print(c)
Lua 学习之基础篇十<Lua 常见的语法规则>的更多相关文章
- Lua 学习之基础篇七<Lua Module,Package介绍>
Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require ...
- Lua 学习之基础篇四<Lua table(表)>
table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组.字典等. Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil. Lua ta ...
- Lua 学习之基础篇一<Lua 运算符>
引言 由于刚接触lua,个人觉得接触一门新语言,就要一定要对基础的部分做一个快速了解. 于是参考网上相关资料吸收并整理下来作为笔记,模糊的时候用来回顾一下. 这些部分基本都是经过自己手动测试梳理过,没 ...
- Lua 学习之基础篇九<Lua 协同程序(Coroutine)>
引言 讲到协程,首先来介绍一下线程和协程的区别 lua协程和多线程 相同之处:拥有自己独立的桟.局部变量和PC计数器,同时又与其他协程共享全局变量和其他大部分东西 不同之处:一个多线程程序可以同时运行 ...
- Lua 学习之基础篇八<Lua 元表(Metatabble)&&继承>
讲到元表,先看一段table的合并动作. t1 = {1,2} t2 = {3,4} t3 = t1 + t2 attempt to perform arithmetic on a table val ...
- Lua 学习之基础篇六<Lua IO 库>
引言 I/O 库提供了两套不同风格的文件处理接口. 第一种风格使用隐式的文件句柄: 它提供设置默认输入文件及默认输出文件的操作, 所有的输入输出操作都针对这些默认文件. 第二种风格使用显式的文件句柄. ...
- Lua 学习之基础篇五<Lua OS 库>
lua os库提供了简单的跟操作系统有关的功能 1.os.clock() 返回程序所运行使用的时间 local nowTime = os.clock() print("now time is ...
- Lua 学习之基础篇三<Lua 字符串操作>
Lua字符串可以使用以下三种方式表示: 单引号间的一串字符. 双引号间的一串字符. [[和]]间的一串字符. string = [["Lua"]] print("字符串 ...
- Lua 学习之基础篇二<Lua 数据类型以及函数库 汇总>
引言 前面讲了运算符,这里主要对Lua的数据处理相关的数据类型和函数库进行总结归纳,后面会再接着单独分开讲解具体使用. 首先因为Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储 ...
随机推荐
- Soda Machine【差分+离散化】
题目链接:https://ac.nowcoder.com/acm/contest/1106/A 题目大意: 1.一条长1e9的线段,每个节点都可以上色.给出n次操作,每次操作将[l, r]区间内的节点 ...
- 正则与re模块
一.正则表达式 在线测试工具 http://tool.chinaz.com/regex/ 1.字符组 在同一个位置可能出现的各种字符组成一个字符组,在正则表达中用[ ]表示 一个正则就是一条匹 ...
- 使用Python比较MySQL数据库中两个数据库的表结构--转载
https://blog.csdn.net/tenaguan4461/article/details/82286781 https://www.jianshu.com/p/b3dac5a3479a
- go 包的概念
------------------------------------------------------------------ package main import ( "fmt&q ...
- scratch少儿编程第一季——07、人要衣装佛靠金装——外观模块
各位小伙伴大家好: 上期我们学习了如何设置背景,和设计一个小项目总结了动作模块. 本期开始我们学习外观模块下的指令. 首先我们来看看前面两个指令 第一个指令是在角色对象上出现一个对话框,显示角色所说的 ...
- shell习题第26题:监控mysql服务
[题目要求] 假设mysql密码是123456. 写脚本监控mysql服务是否正常,比如是否可以执行show processlist,并检测一下当前的mysql服务是主还是从.如果是从,请判断他的主从 ...
- dg环境连接ORA-00604,ORA-16000: database open for read-only access
报错信息 根据客户提供的报错信息, ORA-: error occurred at recursive SQL level ORA-: database open for read-only acce ...
- B-JUI文档、下载
概述 特别说明 本文档仅适用于最新版的B-JUI,网站首页或下载页可以查看B-JUI的最后更新时间. B-JUI前端管理框架适用于快速开发各类WEB管理系统,可与任意后端程序(java.php..ne ...
- 不遮挡人物弹幕是怎么实现的——图片蒙版效果-webkit-mask
这是一个实验中的功能,用于设置元素上遮罩层的图像. 一.Values none:默认值,透明的黑色图像层,也就是没有遮罩层. <mask-source>:<mask>或CSS图 ...
- 博客自定义1-皮肤模板 基于SimpleMemory 添加到顶部小按钮
周五公司事不是很紧,打算好好弄下自己的博客,这是自己学习和记录分享地方, 首先请记得申请js权限,默认不支持的,博主是已经申请通过后的样子 接着先选择cnblogs一个现有的模板,我这个就是在他的模板 ...