下面讲一些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 常见的语法规则>的更多相关文章

  1. Lua 学习之基础篇七<Lua Module,Package介绍>

    Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require ...

  2. Lua 学习之基础篇四<Lua table(表)>

    table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组.字典等. Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil. Lua ta ...

  3. Lua 学习之基础篇一<Lua 运算符>

    引言 由于刚接触lua,个人觉得接触一门新语言,就要一定要对基础的部分做一个快速了解. 于是参考网上相关资料吸收并整理下来作为笔记,模糊的时候用来回顾一下. 这些部分基本都是经过自己手动测试梳理过,没 ...

  4. Lua 学习之基础篇九<Lua 协同程序(Coroutine)>

    引言 讲到协程,首先来介绍一下线程和协程的区别 lua协程和多线程 相同之处:拥有自己独立的桟.局部变量和PC计数器,同时又与其他协程共享全局变量和其他大部分东西 不同之处:一个多线程程序可以同时运行 ...

  5. Lua 学习之基础篇八<Lua 元表(Metatabble)&&继承>

    讲到元表,先看一段table的合并动作. t1 = {1,2} t2 = {3,4} t3 = t1 + t2 attempt to perform arithmetic on a table val ...

  6. Lua 学习之基础篇六<Lua IO 库>

    引言 I/O 库提供了两套不同风格的文件处理接口. 第一种风格使用隐式的文件句柄: 它提供设置默认输入文件及默认输出文件的操作, 所有的输入输出操作都针对这些默认文件. 第二种风格使用显式的文件句柄. ...

  7. Lua 学习之基础篇五<Lua OS 库>

    lua os库提供了简单的跟操作系统有关的功能 1.os.clock() 返回程序所运行使用的时间 local nowTime = os.clock() print("now time is ...

  8. Lua 学习之基础篇三<Lua 字符串操作>

    Lua字符串可以使用以下三种方式表示: 单引号间的一串字符. 双引号间的一串字符. [[和]]间的一串字符. string = [["Lua"]] print("字符串 ...

  9. Lua 学习之基础篇二<Lua 数据类型以及函数库 汇总>

    引言 前面讲了运算符,这里主要对Lua的数据处理相关的数据类型和函数库进行总结归纳,后面会再接着单独分开讲解具体使用. 首先因为Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储 ...

随机推荐

  1. Java面试 - == 和 equals 的区别?

    ==:如果比较的对象是基本数据类型,则比较的是数值是否一致:如果比较的是引用数据类型,则比较的是对象的地址值是否一致. equals():equals()方法不能用于比较基本数据类型的对象,如果对象和 ...

  2. 1254: 盒子游戏(Java)

    WUSTOJ 1254: 盒子游戏 参考博客 叶剑飞Victor的博客 盒子游戏--爱程序网 原理是从上面博客看的,我另外补充了几幅图,方便理解 Description 有两个相同的盒子,其中一个装了 ...

  3. Spring @Transactional注解在什么情况下会失效,为什么?

    出处:  https://www.cnblogs.com/hunrry/p/9183209.html   https://www.cnblogs.com/protected/p/6652188.htm ...

  4. 原生js分页器插件

    window.page = function page(ele, para) { this.ele = document.querySelector(ele); this.options = { co ...

  5. (二)Struts.xml文件详解

    一.Struts.xml文件 Struts.xml文件构成 如图,<Struts>标签内共有5个子标签. 1.1 struts-default.xml 查看Struts的内容可知,Stru ...

  6. tiny-Spring【2】逐步step分析-新加入特性

    tiny-Spring是黄亿华大佬自己写的一个集合IOC和AOP于一身的一种轻量级[教学用]Spring框架,它的github库地址为:https://github.com/code4craft/ti ...

  7. 在论坛中出现的比较难的sql问题:4(row_number函数+子查询 分组连续编号问题)

    原文:在论坛中出现的比较难的sql问题:4(row_number函数+子查询 分组连续编号问题) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路. 求一查询语句 http: ...

  8. dll安装到GAC以及引用的方法【转】

    一 首先    程序集(dll) 安装到 GAC 中的方法 所谓的GAC,就是全局程序集缓存(Global Assembly Cache). 针对一些类库项目或用户控件项目在程序开发完成后,有时需要将 ...

  9. 关于Vue中,checkBox等组件在赋值后,点击切换页面未及时更新问题

    我们经常碰到这样的问题,在v-for循环中,给某些组件(此处以checkBox为例)赋值后,组件并不能正常切换, 这是因为数据层太多,render函数没有自动更新,需手动强制刷新. 解决方法:在切换c ...

  10. ntp时间同步简介

    网络时间协议(Network Time Protocol) 安装 # sudo apt-get install ntp 官网下载:http://www.ntp.org/downloads.html 本 ...