

lua变量、数据类型、if判断条件和数据结构table以及【lua 函数】 - 一乐乐
source link: https://www.cnblogs.com/shan333/p/17331661.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、lua变量【 全局变量和局部变量和表中的域】
Lua 变量有三种类型:全局变量和局部变量和表中的域。
▪ 全局变量:默认情况下,Lua中所有的变量都是全局变量。
▪ 局部变量:使用
local
显式声明在函数内的变量,以及函数的参数,都是局部变量。在函数外即使用local
去声明,它的作用域也是当前的整个文件,这相当于一个全局变量。▪ 表中的域:变量的默认值均为
nil
。☺ Lua语言不区分未初始化变量和被赋值为
nil
的变量,因此全局变量无须声明即可使用。
1、全局变量
全局变量,不需要声明,只需要将一个值赋予一个全局变量即可创建了
。
b=10 -- 这个b就是一个全局变量了
print(b)
- 通常没必要删除一个全局变量,如果一个变量生存周期较为短,使用局部变量即可。不过,如果真的想删除全局变量的话,只需将它赋值为nil。
b=nil -- 这个全局变量b就被删除了
print(b)
2、局部变量-使用local 声明
-
Lua 中的变量全是全局变量,哪怕是语句块或是函数里,除非用 local 显式声明为局部变量。
-
局部变量的作用域为从声明位置开始到所在语句块结束。
■ 建议:在Lua中,应尽可能使用局部变量,好处:
- 避免命名冲突
- 访问局部变量的速度比全局变量更快
3、lua表中的域
a = {}
a[10] = 1
for i=1,15,1 do
print(a[i])
end
二、lua数据类型、if判断条件
Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
1、Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
数据类型 | 描述 |
---|---|
nil |
空值,只有值nil属于该类,表示一个无效值 (在条件表达式中相当于false)。 |
boolean | 布尔类型 |
number | 数值类型,相当于C语言的double |
string | 字符串类型,由一对双引号或单引号来表示 |
function | 函数类型,由 C 或 Lua 编写的函数 |
table |
Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的字面量是用{} 表示。 {},表示创建一个空表。 |
thread | 线程类型,表示执行的独立线路,用于执行协同程序 |
userdata | 表示任意存储在变量中的C数据结构 |
2、type(变量名)
- 作用:获取该变量的类型
3、lua 的if 判断条件是理解为是否有效
▷什么时候会【无效】错误失败---为nil和false的时候
- nil 表示空值、无效值
▷其他情况为数字、字符串、true、表(甚至是空表也是正确的),判断条件都是【有效】正确成功的!
三、lua数据结构-table
0、table的字面量:{}
,创建的空表,内部的域默认值是nil。
- 表用大括号{}来构造,可以是多维的 {{}}。
1、lua中的表,其实是一个"关联数组",关联数组是一种具有特殊索引的数组,数组的索引可以是数组、字符串、表等[除了nil]。
- 表中的元素是键值对形式。key 也就是数组的索引。表的key是唯一的。表是可以自定义键名。
2、table 是没有固定大小的,可以添加任意数量的元素到数组中。
3、table 是lua中最主要的数据结构机制,也是唯一的数据结构。用它可以实现数组,哈希表、集合、字典等等。还可以通过table 表示对象、包、模块。
其实lua 中的table 概念,相当于java中的对象的概念。万物皆是对象。
4、表中元素的删除,有两种方式:直接设置为nil或调用remove方法删除
- 两种删除方式的区别:直接把元素赋值为nil,会留下空位,不影响其他元素。而用remove函数去删除,会把后面的元素往前移,补位。
5、表中元素有多少个,可以使用#获取
6、表中的索引是从1开始的
tb={'干饭', '吃饭', '恰饭'}
- 实际上,tb如下:
-- tb的情况如下:
-- 地址table(c917ad2)
{
[1] = '干饭',
[2] = '吃饭',
[3] = '恰饭',
}
7、表有自定义键的时候:
-- 表中只写了值value作为元素
tb={'干饭', '吃饭', '恰饭', s='溜达'}
- 实际上,表是有默认分配键key的,默认分配的键是从数字1开始的,tb表中的分配如下:
-- tb的情况如下:
-- 地址table(c917ad3)
{
[1] = '干饭',
[2] = '吃饭',
[3] = '恰饭',
['s'] = '溜达',--细节:s会被带上引号
}
细节:要通过自定义的s键获取到值,s是要加上引号的。

对于自定义的键有一个语法糖,中括号可以使用点代替
表中默认分配的键和自定义键的执行顺序是:默认的先执行,然后再是自定义的键
-- 表中只写了值value作为元素
tb={'干饭',a='溜达',b='哈哈哈', _='饿了么','吃饭', '恰饭'}
- 实际上,tb表中的分配如下:程序分配键的时候,会先跳过自定义键,再接着分配。
-- tb的情况如下:
-- 地址table(c917ad3)
{
[1] = '干饭',
[2] = '吃饭',
[3] = '恰饭',
['a'] = '溜达',
['b'] = '哈哈哈',
['_'] = '饿了么',
}
8、table 提供的增删元素的方法 table.insert 和 table.remove
-
table.insert(表名,要增加的键位,要增加的值) 直接再最后的位置增加元素:table.insert(表名,要增加的值)
-
table.remove(表名,要删除的键位)
四、lua 函数(形参-实参数数量不匹配、多重返回值、不定长参数、方法的冒号和点-self隐式参数)
0、lua 程序是严格从上到下的顺序执行代码的, 函数的声明必须在写函数调用前面。

在lua中,函数是作为第一类型,
函数是可以存在在变量中,也可以通过参数传递给其他函数,还可以作为其他函数的返回值,还可以作为table表中的键
1、函数定义的方式
-- 方式1:
function 函数名(参数列表)
函数内容
end
-- 方式2:
函数名=function(参数列表)
函数内容
end
2、lua 函数
① 函数是可以存在在变量中【匿名函数
】
a = function(x, y)
return x * y
end
b = a
print(b(2,3))
▪ 在table中也可以存在function函数
tab = {
test=function()
print("Hello World!")
end
}
tab.test()
Hello World!
3、形参-实参数数量不匹配
- 传入的实参数量 > 定义的形参数量:多传入的参数,直接被忽略了
- 传入的实参数量 < 定义的形参数量:缺少的参数,使用nil替补
4、多重返回值

- 小细节:多个具有多重返回值的函数连续调用[使用,间隔],只有最后一个函数被展开,即最后一个函数才有资格返回多个值,其他函数都默认返回第一个值
5、不定长参数
- 和java 一样,不定长参数使用...表示,并且作为函数的最后一个参数。
- 用 select 函数来访问变长参数了
- select('#', …) 返回可变参数的长度。
- select(n, …) 用于返回从起点 n 开始到结束位置的所有参数列表。

6、方法的冒号和点-self隐式参数
▷ Lua 定义或调用方法时的语法糖-冒号,表示参数self
这个语法糖是用冒号,表示self,相当于java中的this
■ 举例1:
--定义
Account = { balance = 0 }
--withdraw 方法有两个参数,一个self【相当于java中的this】是指向当前table的Account
function Account.withdraw(self, v)
self.balance = self.balance - v
end
--等价写法:
function Account:withdraw(v) --通过冒号,表示定义了第一个参数是self
self.balance = self.balance - v
end
--调用
Account.withdraw(self, 100)
--等价写法
Account:withdraw(100)
■ 举例2:
-- 在table的键值对的value---是function的时候,方法的参数是self,并且还将self 参数传递给function方法体的另外一个方法
-- {} 在lua中表示table
tbWnd.tbOnClick = {
btnOk = function(self)
self:onClickOK() -- 相当于onClickOK(self)
end,
}
7、函数嵌套调用,并且作为参数的那个函数,它是需要有参数传入
① 通过将参数存储到table中,table又绑定上的函数,该函数就可以通过self.key 拿到参数
② 然后外层的函数(func,table)
local tbTable = {}
tbTable.key1 = 1
function tbTable:func1()--这样写,隐式参数是self
print(self.key1)
end
-- 函数嵌套调用
function func2(func,tbSelf)
func(tbself)
end
-- 执行
func(tbTable.func1)
☺ 五、lua 函数常见写法
1、直接构建
function func(...)
print(...)
end
-- 调用函数
func(123)
2、表构建,key存储函数(1)
local tbTable = {}
function tbTable.func1(...)
print(...)
end
function tbTable.func2(...)
print(...)
end
-- 调用函数
tbTable.func1(123)
tbTable.func1(4,5,6)
3、表构建,key存储函数(2)
local tbTable = {}
tbTable.func1 = function(...)
print(...)
end
tbTable.func2 = function(...)
print(...)
end
-- 调用函数
tbTable.func1(123)
tbTable.func1(4,5,6)
4、表构建,key存储函数(3)
local tbTable = {
func1 = function(...)
print(...)
end,
func2 = function(...)
print(...)
end
}
-- 调用函数
tbTable.func1(123)
tbTable.func1(4,5,6)
六、函数嵌套|闭包
1、local 特点:
局部变量:使用local
显式声明在函数内的变量,以及函数的参数,都是局部变量。
在函数外即使用local去声明,它的作用域也是当前的整个文件,这相当于一个全局变量。
2、函数嵌套|闭包
(1) 特点:函数的调用是用() 表示,有多少层,函数真正调用就需要多少个()
(2) 举例子:
- 举例子1:
local f = function(n)
return function(x)
return x+n
end
end
print(f(1)(2)) -- 函数嵌套,每一层都相当于()
a = f(1)
print(a(10))
- 举例子2:local 在函数外相当于java的全局变量【独立的作用域强调的就是这个在函数外面的local 变量】
local p = 1
local f = function()
local v = 0 -- local 在[下面的]函数外面相当于java的全局变量
return function()
v = v + p
print(v)
end
end
a,b = f(), f()
a(); b();
p = 2
a(); b();
-
local 在函数外相当于java的全局变量【独立的作用域】
class A{
private int v; -- 全局变量
public void add(){}
}
- 举例子3:
local f = function()
return {
add = function(a,b)
return a + b
end,
sub = function(a,b)
return a - b
end,
}
end
v = f()
print(v.add(1,2))
print(v.sub(2,1))
如果本文对你有帮助的话记得给一乐点个赞哦,感谢!
Recommend
-
22
其实本文不是介绍 条件分支语法 的, 只介绍测试(test)语法,也就是说:本文只介绍如何写条件语法中的 表达式...
-
13
写给.NET开发者的Python教程(三):运算符、条件判断和循环语句 本节会介绍Python中运...
-
10
为什么都不用 switch 而使用 if/ else 来做条件判断? 乐学小乐 · 大约5小时之前 · 35 次点击 · 预计阅读时间 2 分钟 · 不到1分钟之前 开始浏览 ...
-
11
我们在 Spring/ Spring Boot Starter 或者一些框架的源码里经常能看到类似如下的注解声明,可能作用在类上,也可能在某个方法上: @ConditionalOnProperty(name = "spring.cloud.refresh.enabled", matchIfMissing = true) @Condition...
-
10
V2EX › 程序员 给定若干个条件,怎么判断这些条件彼此互斥 murmur · 5 小时 35 分...
-
5
使用typeof进行判断语法:typeof 判断的数据 特点:可以准确判断基本数据类型,无法对复杂数据类型进行准确判断使用constructor进行判断语法:对象名.construc...
-
7
最近开始读之前没有读完的 underscore 的源码,刚把 Object 部分读完。对 JavaScript 中类型判断部分的总结。 Object.prototype.toString() 在进行类型判断时,使用到最多的当属 Object.prototype.toString()。 toSt...
-
5
如何根据eth的tx详情数据判断该交易的类型? | 登链社区 | 技术问答 5 如何根...
-
8
Javascript 判断数据类型2022年8月25日 by anzhihe·
-
4
JavaScript判断变量类型的四种方法 typeof(根...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK