lua基础知识点总结

 

目录

1.Lua安装

2. 注释

3.Lua中的数据类型

3.1 nil(空)

3.2  boolean(布尔)

3.3 number(数字)

3.4 string(字符串)

3.5 table(表)

3.6 function(函数)

4.全局变量

多变量同时赋值

5.Lua 循环

5.1  while循环

5.2  for循环

5.3  repeat until循环(do...while)

5.4 无限循环(这里就不运行了,你懂的。)

5.5 循环嵌套

6.Lua流程控制

7.Lua函数

可变参数

8.Lua运算符

运算符优先级

9.转义字符:

10.Lua字符串

11.数组(在 Lua 中索引值默认是以 1 为起始,但你也可以指定 0或其他值 开始。)

  一维数组:

多维数组:

12.Lua中的迭代器函数-pairs ipairs

自定义Lua迭代函数

13.Lua table(表)

Table 连接

Table 插入

Table 删除表内数据

Table 排序- sort()函数

Table 最大值

14.Lua 模块(相当于“类”)

15.Lua 元表(Metatable)

__index 元方法

总结

__newindex 元方法

__tostring 元方法

__call 元方法

为表添加操作符

16.Lua 协同程序(coroutine)

线程和协同程序区别:

在协同函数中返回值(比较以下4个例子)

17.Lua 文件 I/O

文件的读取:file = io.open (filename [, mode])

文件的写入:io.open(filename [, mode])

读取下一行:io.read("*l")

读取所有内容:io.read("*a")

返回一个指定字符个数的字符串

18.Lua 垃圾回收

19.Lua 面向对象

面向对象特征

Lua 中面向对象介绍

通过冒号和点来定义调用函数的使用区别

创建构造函数


1.Lua安装

       Lua下载路径:https://github.com/rjpcomputing/luaforwindows/releases

 

   Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

      C#都要编译成dll才能运行,而lua可以直接把源文件放到程序里边。

      lua语句可不写分号“;”

2. 注释

      单行:--                多行:--[[     --]]

3.Lua中的数据类型

    Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。

print(type("helloWorld"))
print(type(10))
print(type(1.1))
print(type(print))
print(type(type))
print(type(nil))
print(type(x))

3.1 nil(空)

         nil 类型表示一种没有任何有效值,它只有一个值 -- nil

       对于全局变量和 table,nil 还有一个"删除"作用,给全局变量或者 table 表里的变量赋一个 nil 值,等同于把它们删掉

tab1 = { key1 = "val1", key2 = "val2", "val3" }
for k, v in pairs(tab1) do
    print(k .. " - " .. v)
end

print("--------------")

tab1.key1 = nil
for k, v in pairs(tab1) do
    print(k .. " - " .. v)
end

3.2  boolean(布尔)

     boolean 类型只有两个可选值:true(真) 和 false(假),Lua 把 false 和 nil 看作是"假",其他的都为"真":

if false or nil then
    print("至少有一个是 true")
else
    print("false 和 nil 都为 false!")
end

print("-------------")
print(type(true))
print(type(false))
print(type(nil))

3.3 number(数字)

       Lua 默认只有一种 number 类型 -- double(双精度)类型(默认类型可以修改 luaconf.h 里的定义),以下几种写法都被看作是 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))

3.4 string(字符串)

     Lua中,“+”只能做加法运算,不能做字符串组拼,字符串组拼用“..

str1="this is string1"
str2="this is string2"

print("2".."6")
print("2"+"6")

print("2"+6)
print("2+6")
print("2e2"*"6")

print("--------")

print(#str1)

3.5 table(表)

在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表:

tab1 = {}        -- 创建一个空的 table
print(tab1)
print(tab1.key)
print("--------------")

tab1.key1="lijiang"
tab1["key2"]="lijiang"
tab1[10]=1000
print(tab1.key1)
print(tab1["key1"])
print(tab1.key2)
print(tab1["key2"])
print(tab1[10])
print(tab1[2])
print("--------------")

print(tab1[1])
tab1[1]=100
print(tab1[1])
print(tab1["key1"])
print("--------------")

tab2={key1=100,key2="value2"}
print(tab2.key1)
print(tab2["key1"])
print(tab2[1])
print(tab2["1"])
print("--------------")


tab3 = {"apple", "pear", "orange", "grape"}  -- 直接初始表
print(tab3[2])
print(tab3["2"])
print(tab3["pear"])
print(tab3["key2"])

Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。 

a = {}
a["key1"] = "value"

key = 10
a[key] = 22
a[key] = a[key] + 11
for k, v in pairs(a) do
    print(k .. " : " .. v)
end

不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始。

local tbl = {"apple", "pear", "orange", "grape"}
for key, val in pairs(tbl) do
    print("Key", key)
end

table 不会固定长度大小,有新数据添加时 table 长度会自动增长,没初始的 table 都是 nil。

a3 = {}
for i = 1, 10 do
    a3[i] = i
end
a3["key"] = "val"
print(a3["key"])
print(a3["none"])

3.6 function(函数)

在 Lua 中,函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里:

function factorial1(n)
    if n == 0 then
        return 1
    else
        return n * factorial1(n - 1)
    end
end
print(factorial1(4))
factorial2 = factorial1
print(factorial2(4))

function 可以以匿名函数(anonymous function)的方式通过参数传递:

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
);

 

4.全局变量

变量在使用前,必须在代码中进行声明,即创建该变量。

Lua 变量有三种类型:全局变量、局部变量、表中的域。

Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量。

局部变量的作用域为从声明位置开始到所在语句块结束。

变量的默认值均为 nil。

全局变量不需要声明,给一个变量赋值后即创建了这个全局变量,访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil。

print(b)

b=10
print(b)

如果你想删除一个全局变量,只需要将变量赋值为nil。

b=nil
print(b)

这样变量b就好像从没被使用过一样。换句话说, 当且仅当一个变量不等于nil时,这个变量即存在。

多变量同时赋值

a, b, c = 0, 1
print(a,b,c)

a, b = a+1, b+1, b+2
print(a,b)

a,b=b,a
print(a,b)

a, b, c = 0
print(a,b,c)
print("------------")

function test()
      return 10,20
end
a,b=test()
print(a,b)

5.Lua 循环

5.1  while循环

格式:
while (condition) do
     statements
end
a=1
while (a<5) do
 print(a)
 a=a+1
end

 

5.2  for循环

        1.数值for循环

格式:(这里var会从start变化到end,每次变化step。step默认为1)
for var=start,end,step do 
        循环体
end
for i=1,10,2 do
	print(i)
end

        2.泛型for循环

tab1={key1="lijiang",key2=10}
for k,v in pairs (tab1) do
    print(k,v)
end

5.3  repeat until循环(do...while)

a=1
repeat
    print(a)
	a=a+1
until(a>5)

5.4 无限循环(这里就不运行了,你懂的。)

while( true )
do
   print("循环将永远执行下去")
end

可用break退出

5.5 循环嵌套

for i=1,4 do
  for j=1,i do
    print(i)
  end
end

或者:

for i=1,4 do
  j=1
  while j<=i do
    print(i)
	j+j+1
  end
end

6.Lua流程控制

--当条件表达式为false或此处为nil时,为false;其余情况都为true
if(condition为true)  then  

  xxx
end


if(condion为true)  then
  xxx
else
  xxx
end


if(condition为true) then
    xxx
  elseif() then
    xxx
  elseif() then
    xxx
end

7.Lua函数

local function max(num1,num2)
       if(num1>num2) then
	      return num1
	    else
		  return num2
		end
	end
print(max(1,10))
print("-----------")

temp=max
print(temp(2,5))


myprint=function(param)
   print("这是我的打印函数:"..param)
end
myprint(100)
print("-----------")

function add(a,b,printFun)
         res=a+b
		 printFun(res)
end
add(20,30,myprint)
print("-----------")

function tem()
   return 1,3,54,65
end
a,b,c,d,e,f=tem()
print(a,b,c,d,e,f)

可变参数

Lua 函数可以接受可变数目的参数,和 C 语言类似,在函数参数列表中使用三点 ... 表示函数有可变的参数。

--lua里面的函数可以返回多个值
function test(...)
   local arg={...}
   res=0
   for k,v in pairs(arg) do
	  res=res+v
	end
    print(res)
end

test()
test(10)
test(1,2)
test(1,2,3,4,5)

8.Lua运算符

其他的和c#差不多,不同的是:

      不等于:~=              and / or / not

..连接两个字符串a..b ,其中 a 为 "Hello " , b 为 "World", 输出结果为 "Hello World"。
#一元运算符,返回字符串或表的长度。#"Hello" 返回 5

运算符优先级

从高到低的顺序:

^
not    - (unary)
*      /
+      -
..
<      >      <=     >=     ~=     ==
and
or

9.转义字符:

--字符串定义: “” , ‘’ ,[[]]
--转义字符 :\n 换行   \\代表一个反斜杠  \"代表"  \'代表'


a='Hello\nWorld\\hahaha'
print(a)
b=" \'    \" "
print(b)

10.Lua字符串

Lua 提供了很多的方法来支持字符串的操作:

序号方法 & 用途
1string.upper(argument):
字符串全部转为大写字母。
2string.lower(argument):
字符串全部转为小写字母。
3string.gsub(mainString,findString,replaceString,num)
在字符串中替换,mainString为要替换的字符串, findString 为被替换的字符,replaceString 要替换的字符,num 替换次数(可以忽略,则全部替换),如:
> string.gsub("aaaa","a","z",3);
zzza    3
4string.find (str, substr, [init, [end]])
在一个指定的目标字符串中搜索指定的内容(第三个参数为索引),返回其具体位置。不存在则返回 nil。
> string.find("Hello Lua user", "Lua", 1) 
7    9
5string.reverse(arg)
字符串反转
> string.reverse("Lua")
auL
6string.format(...)
返回一个类似printf的格式化字符串
> string.format("the value is:%d",4)
the value is:4
7string.char(arg) 和 string.byte(arg[,int])
char 将整型数字转成字符并连接, byte 转换字符为整数值(可以指定某个字符,默认第一个字符)。
> string.char(97,98,99,100)
abcd
> string.byte("ABCD",4)
68
> string.byte("ABCD")
65
>
8string.len(arg)
计算字符串长度。
string.len("abc")
3
9string.rep(string, n)
返回字符串string的n个拷贝
> string.rep("abcd",2)
abcdabcd
10..
链接两个字符串
> print("www.runoob".."com")
www.runoobcom

11.数组(在 Lua 中索引值默认是以 1 为起始,但你也可以指定 0或其他值 开始。)

  一维数组:

a={}
a[-2]=1
print(a[-2])

b={-1,0,1}
print(b[-1],b[0],b[1])

多维数组:

array = {{},{},{}}
for i=1,3 do
      for j=1,3 do
         array[i][j] = i*j
		 print(array[i][j])
      end
end

arr={{"张三","李四"},{"王五","赵六"},{"前期","孙吧"}}
print(arr[1][1])
print("---------")

-- 访问数组
for i=1,3 do
   for j=1,2 do
      print(arr[i][j])
   end
end

12.Lua中的迭代器函数-pairs ipairs

pairs迭代table,遍历表中所有的key和value

ipairs按照索引从1开始,递增遍历,遇到nil就停止

arr={"lua","c","java"}
for k,v in pairs(arr) do
     print(k,v)
end
print("----------")

arr[2]=nil
for k,v in ipairs(arr) do
     print(k,v)
end

自定义Lua迭代函数

  for 变量列表 in 迭代函数,状态变量,控制变量 do
          循环体
   end

1.调用迭代函数,把状态变量和控制变量当做参数传递给迭代函数,状态变量只会在第一次调用的时候赋值

2.如果迭代函数的返回值为nil,退出for循环。如果不是nil的话,把返回值赋值给变量列表,并执行循环体

function square(state,control)
   if(state<=control) then
         return nil
    else
	    control=control+1
		return control,control*control
	end
end

for i,j in square,4,0 do
    print(i,j)
end

13.Lua table(表)

Table 连接

mytable={"lua","java","c++","c#","c"}
print(table.concat(mytable))
print(table.concat(mytable,","))      --中间用逗号隔开    
print(table.concat(mytable,",",2,4))  --只连接索引2到4的数据

Table 插入

mytable={"lua","java","c++","c#","c"}
print(#mytable)
print(mytable[#mytable])
print("-----------")

mytable[#mytable+1]="php"
print(mytable[#mytable])
print("-----------")

table.insert(mytable,"javascript")
print(mytable[#mytable])
print("-----------")

table.insert(mytable,2,"Boo")
print(mytable[1],mytable[2],mytable[3])

Table 删除表内数据

mytable={"lua","java","c++","c#"}
print(mytable[1],mytable[2],mytable[3],mytable[4])
print("-----------")

table.remove(mytable,2)
print(mytable[1],mytable[2],mytable[3],mytable[4])
print("-----------")

mytable[1]=nil
print(mytable[1],mytable[2],mytable[3],mytable[4])

Table 排序- sort()函数

fruits = {"banana","orange","apple","grapes"}
print("排序前:")
for k,v in ipairs(fruits) do
    print(k,v)
end

table.sort(fruits)
print("排序后:")
for k,v in ipairs(fruits) do
    print(k,v)
end

Table 最大值

mytable={123,64,4,34,76,567,8,23}

function GetMaxNum(tab)
  local tem=0
  for k,v in pairs(tab) do
        if(tem<v) then
		   tem=v
		end
	end
	return tem
end

print("表中最大值:",GetMaxNum(mytable))

14.Lua 模块(相当于“类”)

--文件名:module.lua

module = {}
module.constant = "这是一个常量"  -- 定义一个常量
function module.func1()  -- 定义一个函数
    io.write("这是一个公有函数!\n")
end

local function func2()
    print("这是一个私有函数!")
end

function module.func3()
    func2()
end

return module

Lua提供了一个名为require的函数用来加载模块 

-- test_module.lua 文件
-- module 模块为上文提到的 module.lua

require("module")

print(module.constant)

module.func3()

或者给加载的模块定义一个别名变量,方便调用:

-- module 模块为上文提到到 module.lua
-- 别名变量 m
local m = require("module")
 
print(m.constant)
 
m.func3()

15.Lua 元表(Metatable)

mytable={"lua","c","java"}   --普通表
mymetatable={}               --元表  元表扩展了普通表的行为
mytable=setmetatable(mytable,mymetatable)   -- 把 mymetatable 设为 mytable 的元表 
         --也可以写成 mytable=setmetatable({"lua","c","java"},{})
print(mytable[3])
print(mymetatable[3])
print(mymetatable)
print(getmetatable(mytable))

__index 元方法

这是 metatable 最常用的键。

       当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。如果__index包含一个表格,Lua会在表格中查找相应的键。

mytable={"lua","c","java"}
mymetatable={
	__index=function (tab,key)  -- __index前面是2根短横线,不是1根
	   print(tab)
	   print("调用了_index方法:"..key)
	   end
}

mytable=setmetatable(mytable,mymetatable)

print(mytable)
print(mytable[1])
print(mytable[10])

       如果__index包含一个函数的话,Lua就会调用那个函数,table和键会作为参数传递给函数。__index 元方法查看表中元素是否存在,如果不存在,返回结果为 nil;如果存在则由 __index 返回结果。

mytable={"lua","c","java"}
mymetatable={
	__index=function (tab,key)  -- __index前面是2根短横线,不是1根
	   if(key>=10) then
	     return "javascript"
	   end
	end
}

mytable=setmetatable(mytable,mymetatable)

print(mytable)
print(mytable[1])
print(mytable[10])

总结

Lua查找一个表元素时的规则,其实就是如下3个步骤:

  • 1.在表中查找,如果找到,返回该元素,找不到则继续
  • 2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续。
  • 3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值。

__newindex 元方法

         __newindex 元方法用来对表更新,__index则用来对表访问 。

       当给表的一个缺少的索引赋值,解释器就会查找元表中的__newindex 元方法。如果存在__newindex 元方法,则调用这个__newindex 函数而不进行赋值操作,即给这个缺少的索引赋值将会失败。

      而如果给表中已存在的索引赋值,则会进行赋值操作,即赋值将会成功。此时就算元表中存在__newindex 元方法,也不会调用这个__newindex元方法 。

mytable={"lua","c","java"}
mymetatable={
	__newindex=function (tab,key,value)
	   print("要修改的key为:"..key.."把这个key值修改为:"..value)
	end
}

mytable=setmetatable(mytable,mymetatable)
mytable[10]="c#"
mytable[2]="html"

print(mytable[10])
print(mytable[2])

__tostring 元方法

__tostring 元方法用于修改表的输出行为。以下实例我们自定义了表的输出内容:

mytable = setmetatable({ 10, 20, 30 }, {
  __tostring = function(mytable)
    sum = 0
    for k, v in pairs(mytable) do
        sum = sum + v
    end
    return "表所有元素的和为 " .. sum
  end
})
print(mytable)

__call 元方法

__call:可以让表当成函数来使用

mytable={"lua","c","java"}
mymetatable={
     __call=function (mytable,arg1,arg2,arg3)
	     print(arg1,arg2,arg3)
		 return "lijiang"
	   end
}

mytable=setmetatable(mytable,mymetatable)

v=mytable(234,2,64)
print(v)
print("--------------")
print(mytable(234,2,64))

为表添加操作符

这个就不举例了,需要时百度

模式描述
__add对应的运算符 '+'.
__sub对应的运算符 '-'.
__mul对应的运算符 '*'.
__div对应的运算符 '/'.
__mod对应的运算符 '%'.
__unm对应的运算符 '-'.
__concat对应的运算符 '..'.
__eq对应的运算符 '=='.
__lt对应的运算符 '<'.
__le对应的运算符 '<='.

16.Lua 协同程序(coroutine)

        普通函数要执行完才能运行下一段程序,但是协同程序可以在执行过程中暂停执行,在暂停执行中,下一段程序可以继续执行,然后在需要协同程序时,协同程序又可以在上次暂停的地方继续执行。

线程和协同程序区别:

        线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只有在明确的被要求挂起的时候才会被挂起。协同程序有点类似同步的多线程,在等待同一个线程锁的几个线程有点类似协同。

方法描述
coroutine.create()创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用
coroutine.resume()重启coroutine,和create配合使用。resume操作成功返回true,否则返回false;
coroutine.yield()挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果
coroutine.status()查看coroutine的状态
注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序
coroutine.running()返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号
co=coroutine.create(               --创建协同函数
    function(a,b)
	  print(a+b)

	  print(coroutine.status(co))  --查看coroutine的状态 running

	  coroutine.yield()            --挂起协同函数
	  print(a-b)
	  print(coroutine.status(co))  --查看coroutine的状态 running
	end
)

coroutine.resume(co,20,30)         --启动协同函数

print(coroutine.status(co))        --查看coroutine的状态 suspended

print("李疆")

print(coroutine.status(co))        --查看coroutine的状态 suspended

coroutine.resume(co)               --重启协同函数

print(coroutine.status(co))        --查看coroutine的状态 dead

在协同函数中返回值(比较以下4个例子)

例1.

co=coroutine.create(
  function(a,b)
       print(a,b)
	print(a-b)
	return a*b,a/b
  end
)

res1,res2,res3=coroutine.resume(co,10,2)
print(res1,res2,res3)

res=coroutine.resume(co)
print(res)

例2.

co=coroutine.create(
  function(a,b)
         print(a,b)
	coroutine.yield()
	print(a-b)
	return a*b,a/b
  end
)

res1,res2,res3=coroutine.resume(co,10,2)
print(res1,res2,res3)

res=coroutine.resume(co)
print(res)

例3.

co=coroutine.create(
  function(a,b)
    print(a,b)
	coroutine.yield(a*b,a/b)
	print(a-b)

	--return a*b,a/b
  end
)

res1,res2,res3=coroutine.resume(co,10,2)
print(res1,res2,res3)

res=coroutine.resume(co)
print(res)

例4.

co=coroutine.create(
  function(a,b)
    print(a,b)
	coroutine.yield(a*b,a/b)
	print(a-b)
    return a*a,b*b

  end
)

res1,res2,res3=coroutine.resume(co,10,2)
print(res1,res2,res3)

print("李疆")

res1,res2,res3=coroutine.resume(co)
print(res1,res2,res3)

17.Lua 文件 I/O

     mode 的值有:

模式描述
r以只读方式打开文件,该文件必须存在。
w打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
a以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
r+以可读写方式打开文件,该文件必须存在。
w+打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a+与a类似,但此文件可读可写
b二进制模式,如果文件是二进制文件,可以加上b
+号表示对文件既可以读也可以写

文件的读取:file = io.open (filename [, mode])

file=io.open("data.txt","r")
io .input(file)
print(io.read())

io.close(file)

文件的写入:io.open(filename [, mode])

file=io.open("data.txt","w") --[[ “w”:打开只写文件,若文件存在则文件长度清为0,即该文件内容会消
                                失。若文件不存在则建立该文件--]]
io .output(file)
io.write("lijiang")
io.close(file)

file=io.open("data.txt","a")  --[["a":以附加的方式打开只写文件。若文件不存在,则会建立该文件,如
                          果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留--]]
io .output(file)
io.write("李疆啦啦啦啦")
io.close(file)

模式描述
"*n"读取一个数字并返回它。例:file.read("*n")
"*a"从当前位置读取整个文件。例:file.read("*a")
"*l"(默认)读取下一行,在文件尾 (EOF) 处返回 nil。例:file.read("*l")
number返回一个指定字符个数的字符串,或在 EOF 时返回 nil。例:file.read(5)

读取下一行:io.read("*l")

file=io.open("data.txt","r")
io .input(file)
print(io.read("*l"))  --读取下一行
print(io.read("*l"))  --读取下一行
io.close(file)

读取所有内容:io.read("*a")

file=io.open("data.txt","r")
io .input(file)
print(io.read("*a"))  --读取所有内容
io.close(file)

返回一个指定字符个数的字符串

file=io.open("data.txt","r")
io .input(file)
print(io.read(5))
print(io.read(2))
io.close(file)

18.Lua 垃圾回收

       collectgarbage("collect"): 做一次完整的垃圾收集循环。

       collectgarbage("count"): 以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)。

mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

19.Lua 面向对象

面向对象特征

  • 1) 封装:指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性。
  • 2) 继承:继承的方法允许在不改动原程序的基础上对其进行扩充,这样使得原功能得以保存,而新功能也得以扩展。这有利于减少重复编码,提高软件的开发效率。
  • 3) 多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
  • 4)抽象:抽象(Abstraction)是简化复杂的现实问题的途径,它可以为具体问题找到最恰当的类定义,并且可以在最恰当的继承级别解释问题。

Lua 中面向对象介绍

我们知道,对象由属性和方法组成。LUA中最基本的结构是table,所以需要用table来描述对象的属性。

lua中的function可以用来表示方法。那么LUA中的类可以通过table + function模拟出来。

至于继承,可以通过metetable模拟出来(不推荐用,只模拟最基本的对象大部分时间够用了)。

Lua中的表不仅在某种意义上是一种对象。像对象一样,表也有状态(成员变量);也有与对象的值独立的本性,特别是拥有两个不同值的对象(table)代表两个不同的对象;一个对象在不同的时候也可以有不同的值,但他始终是一个对象;与对象类似,表的生命周期与其由什么创建、在哪创建没有关系。对象有他们的成员函数,表也有

例1

person={name="lijiang",age="20"}

function person.eat()
  print(person.name.."在吃饭")
end

person.eat()

例2.

person={name="lijiang",age="20",
			eat=function()
               print(person.name.."在吃饭")
			end
}

print(person.age)
person.eat()

通过冒号和点来定义调用函数的使用区别

         当通过“.”来调用函数的时候,self不会自动赋值,我们必须通过第一个参数来传递当前的table;

         当用“:”调用函数的时候,系统会自动传递当前的table给self;(强烈推荐

例1.(用“.”来调用函数的情况)

person={name="lijiang",age="20"}

function person.eat(self)
  print(self.name.."在吃饭")
end

a=person
person=nil

a.eat(a)

例2.(用“:”来调用函数的情况)(推荐)

person={name="lijiang",age="20"}

function person:eat()
  print(self.name.."在吃饭")
end

a=person
person=nil

a:eat()

创建构造函数

person={name="lijiang",age="20"}

function person:eat()
  print(self.name.."在吃饭")
end

function person:new()
  t={}
  setmetatable(t,{__index=self})
  return t
end

person1=person:new()
print(person1.name)

person1:eat()

person1.name="李疆"
person1:eat()

person={name="lijiang",age="20"}

function person:eat()
  print(self.name.."在吃饭")
end

function person:new(a)
  t=a or {}
  setmetatable(t,{__index=self})
  return t
end

person1=person:new({a=100})
person1:eat()

person1.name="李疆"
person1:eat()

print(person1.a)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 20
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值