联系我们 - 广告服务 - 联系电话:
您的当前位置: > 综合 > > 正文

热门看点:Lua是什么?javaLua应用场景游戏开发

来源:CSDN 时间:2023-04-24 09:36:27

目录


(资料图片仅供参考)

Lua是什么Lua应用场景Lua和C#的区别print方法、单行/多行注释Lua命名规则(标识符)全局变量的使用和销毁Lua中的数据类型nil 空类型boolean 布尔类型number数字类型string字符串类型table表类型function函数thread和userdata类型 全局变量和局部变量的声明和使用循环while循环for循环repeat until循环循环嵌套 流程控制function用法特性总结运算符字符串操作数组迭代器表模块元表(Metatable)__index 元方法__newindex 元方法为表添加操作符__call元方法__tostring 元方法 协同程序(coroutine)Lua中文件的IO垃圾回收实现面向对象

Lua是什么

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua 可以很方便的和其他程序进行集成(c++,c#,java等)

Lua应用场景

游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统

Lua和C#的区别

Lua 可以在几乎所有的操作系统和平台进行编译运行,可以很方便的更新代码,更新了代码后,可以直接在手机上运行,不需要重新安装(比如热更新方案)

C#只能在特定的操作系统中进行编译成dll文件,然后打包进安装包在其他平台(比如 Android、iOS),如若已经运行在移动平台上,不能更新替换已有的dll文件,除非重新下载安装包

print方法、单行/多行注释

print("Hello world")-- 用来表示单行注释--[[用来表示多行注释--]]

Lua命名规则(标识符)

1,不能以数字开头 2,不能是关键字 关键字比如: and//break//do//else//elseif//end//false//for//function等

而且在 Lua 中大小写是敏感的,and 是关键字,And,AND 这是两个不同的标识符

还有_XXX(_ABC)这种不推荐使用(是保留用法,在 Lua 中有特殊的用法)

全局变量的使用和销毁

Lua中变量不需要声明,可以直接使用,也不需要初始化,可以直接使用。 对于没有初始化和声明的变量默认值为 nil(空类型,空值)

b = nil

把一个变量置空(nil),相当于没有使用过这个变量,Lua 会销毁 b 所占的内存

Lua中的数据类型

nil这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。 boolean包含两个值:false和true。 number表示双精度类型的实浮点数 string字符串由一对双引号或单引号来表示 function由 C 或 Lua 编写的函数 userdata表示任意存储在变量中的C数据结构 thread表示执行的独立线路,用于执行协同程序 tableLua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

在 Lua 中有一个 type 方法,它可以返回数据的类型,输出的是 string 字符串,比如:

print(type("Hello world"))      --> stringprint(type(10.4*3))             --> numberprint(type(print))              --> functionprint(type(type))               --> functionprint(type(true))               --> booleanprint(type(nil))                --> nilprint(type(type(X)))            --> string

nil 空类型

没有声明和赋值的变量都是默认 nil 类型 这个 nil 类型下面只有一个值 nil 值 把一个变量赋值为 nil,表示回收并删除这个变量

boolean 布尔类型

这个下面只有两个值 true 和 false false 和 nil 都代表 false,其他任何值都代表 true(0和空字符串 Lua 也都认为是 true)

number数字类型

1,数字的表示方式   4  0.4   4.45e-3  0.3e12  5E+20 2,整数和小数都是 number 类型的   type(3)    type(3.5) 3,如果整数和小数的大小是一样的,那么 Lua 认为就是相等的   1 == 1.0   -3 == -3.0  0.2e3==200 4,如果我们想要区分整数和小数这两种类型,可以使用 math.type 函数   math.type(3)  math.type(3.0)  integer  float 5,1e3 表示一个小数   1000.0 6,支持16进制   0xff  0x1A3  0x0.2

string字符串类型

定义:使用单引号或者双引号表示字符串

1,替换字符串

a="one string";    b=string.gsub(a,"one","another")    print(a)     --> one string    print(b)     --> another string

2,取得字符串的长度#

print(#a)     --> 10    print(#"good bye")     --> 8

3,字符串组拼

"Hello".."World"    "result is"..3

table表类型

表在 Lua 中是一个非常重要的数据结构,也是最有权力的。 1、我们可以使用表表示数组,集合,字典… 2、Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。 3、Lua table 是不固定大小的,你可以根据自己需要进行扩容。 4、表既不是值类型也不是变量,它是对象。 5、Lua 也是通过 table 来解决模块(module)、包(package)和对象(Object)的。 例如 string.format 这里其实 string 并不是一个类。在 Lua 中没有类,Lua 中使用 table 实现类、面向对象这些概念。

tab1 = {} --空表   {}构造表达式        tab2 = {key1=100,key2="value2"} --初始化一个表       tab2[1] = "Lua"   -- 指定值        print(tab1)    print(tab1.key)        print(tab2.key1)    print(tab2["key1"])        tab2 = nil  -- 移除引用 Lua 的垃圾回收会释放内存        tab3 = {"apple","pear","orange","grape"}        print(tab3[2])    print(tab3["2"])        for key,val in pairs(tab3) do    print(key..":"..val)    end        for key,val in pairs(tab2) do    print(key..":"..val)    end

关于表的自动垃圾回收:当我们创建一个表 a 并设置元素,然后将 a 赋值给 b,则 a 与 b 都指向同一个内存。如果 a 设置为 nil ,则 b 同样能访问 table 的元素。如果没有指定的变量指向 a,Lua的垃圾回收机制会清理相对应的内存。

function函数

比如一个求阶乘的函数

function fact(n)if n==1 thenreturn n;elsereturn n*fact(n-1);endendprint(fact(3))print(fact(5))fact2 = factprint(fact2(5))

另一种,关于function函数,作为参数传递和匿名函数的用法

function testFun(tab,fun)    for k ,v in pairs(tab) do        print(fun(k,v));    endendtab={key1="val1",key2="val2"};testFun(tab,function(key,val)--匿名函数    return key.."="..val;end);执行结果为:key1 = val1key2 = val2

thread和userdata类型

在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。 线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。

全局变量和局部变量的声明和使用

全局变量

a = 5 print(type(a))   --> number--类型可变a = "Hello"print(type(a))   --> string

局部变量

--局部变量的销毁是在所在语句块结束local b = 10print(b)function test()c = 5local d = 6endtest()print(c,d)dolocal a = 10b =11print(a,b)endprint(a,b)

多变量赋值

a,b = 10,20   -- a = 10 b = 20a,b,c = 10,20,"Hello"print(a,b,c)a,b = b,a   -- a = b  b = a 也就是 变量交换值print(a,b)a,b = 10,20,30   --多的值自动略去print(a,b)a,b,c = 20,30   --没有值赋值 nilprint(a,b,c)function test()return 40,50enda,b = test()   --返回多个值 并获取print(a,b)

循环

1,while循环 2,for循环 3,repeat unitl (do while)

while循环

while (condition) dostatementsenda = 1while (a<=20) doif (a%2==1) thenprint(a)enda=a+1end

for循环

1,数值for循环

for var=start,end,step do 循环体 end 这里var会从start变化到end,每次变化一step进行

for i=1,10,2 doprint(i)endfor i=20,1,-3 doprint(i)end

2,泛型for循环

tab1 = {key1="value1",key2="value2"}for k,v in pairs(tab1) doprint(k,v)endtab2 = {"apple","橡胶","西瓜","猕猴桃"}for k,v in pairs(tab2) doprint(k,v)end

repeat until循环

repeat 循环体 until(condition)

a = 1repeatprint(a)a=a+1until(a>10)

循环嵌套

for i=1,10 dofor j=1,i doprint(i)endendfor i=1,10 doj=1while j<=i doprint(i)j=j+1endend

流程控制

if (布尔表达式) then 为true的时候要执行的代码 end

if(布尔表达式)then 为true的时候要执行的代码 else 为false的时候要执行的代码 end

if (布尔表达式) then //1 elseif (布尔表达式) then //2 else //3 end

-----if (0) thenprint(0)end-----a  = 10if (a>10) thenprint("a大于10")end-----if a<=10 thenprint("a小于等于10")end-----if (b) thenprint("b不为空")elseprint("b为空")end-----a = 100if (a<=50) thenprint("a<=50")elseif (a<=100) thenprint("a<=100")elseif (a<=150) thenprint("a<=150")elseprint("上面三种情况都不满足")end

function用法特性总结

[local] function functionName(arg1,arg2,arg3…argn)           functionBody           [return value1,value2…valuen] end

local function max(num1,num2)if(num1>num2)thenreturn num1elsereturn num2endendprint( max(1,10) )--函数可以作为数据赋值   可以作为参数传递temp = maxprint(temp(40,3))-----myprint = function (param)print("这个是我的打印函数"..param)endmyprint(100)-----function add(num1,num2,printFun)local res = num1+num2printFun(res)endadd(40,50,myprint)--lua里面的函数可以返回多个值

可变参数 用 ...三个点表示

function average(...)local arg = {...}res = 0for k,v in pairs(arg) dores = res+vend-- #arg 取得参数的个数  #"hello"print(res/#arg)endaverage(10)average(1,30)average(3,8,90)average(5,67,7,8,3)

运算符

算术运算符:+ - * / % ^求幂 -

关系运算符: == ~= > < >= <=

if(a==b)thenprint("a==b")elseprint("a~=b")end-----if(a~=b)thenprint("ab不相等")elseprint("ab相等")end-----if(a<B)THENPRINT("A小于B")ELSEPRINT("A不小于B")END< code="">

逻辑运算符 and or not a and b a ,b 都为true则结果为true a or b a,b中只要有一个为true,结果为true not a 非/取反

print( 30>20 and 10>30)print( false or false  )print (not true)

字符串操作

str ="My name is MoGu! name"str2 =string.upper(str)str3 =string.lower(str)str4 =string.gsub(str,"i","123",5)index = string.find(str,"name",5) --返回所查找到的位置的索引str5=string.reverse(str)num1 = 5num2 = 10print(str,str2,str3,str4,index)print(str5)print("加法运算:"..num1.."+"..num2.."="..(num1+num2))username = "w3er4wwrfwer"password = "lkjlw3e4rl"print("select * from user where username = ""..username.."" and password =""..password..""")str6=string.format("加法运算:%d+%d=%d",num1,num2,(num1+num2))print(str6)str7 = string.format("select * from user where username="%s" and password ="%s"",username,password)print(str7)date = 2; month = 1; year = 2014print(string.format("日期格式化 %02d/%02d/%03d", date, month, year))s1 = string.char(97,98,99,100)i1 =string.byte("ABCD",4)i2 =string.byte("ABCD")print(s1,i1,i2)length1 = string.len("abc")length2 = #"abc"print(length1,length2)s2=string.rep("abcd",4)print(s2)for word in string.gmatch("Hello Lua user", "%a+") doprint(word)end

数组

Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。

array = {"Lua","C#"}array[3]="Java"for i=1,3 doprint(array[i])endarray = {}for i =-2,2 doarray[i]=i*3endfor i=-2,2 doprint(array[i])end

二维…多维数组

array = { {"小明","小红"},{"小刘","小狼"},{"大明","大刘"},{"小赵","李四"} }  --4*2print(array[3][1])for i =1,4 dofor j=1,2 doprint(array[i][j])endendarray = {{},{},{}}for i = 1,3 doarray[i]={}for j=1,2 doarray[i][j]=i*jendendfor i = 1,3 dofor j=1,2 doprint(array[i][j])endend

迭代器

pairs迭代table,遍历表中所有的key跟value ipars按照索引从1开始,递增遍历,遇到nil值就停止

array = {"Lua","C#","Java"}for k in pairs(array) doprint(k,v)endarray[2]=nilfor k,v in ipairs(array) doprint(k,v)end

整体的结构

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

1,调用迭代函数,(把状态变量和控制变量当做参数传递给迭代函数) 状态变量只会在第一次调用的时候赋值。 2,如果迭代函数的返回值为nil,退出for循环;如果不是nil的话,把返回值赋值给变量列表,并执行循环体。

自定义迭代函数,求平方

function square(state,control)if(control>=state) thenreturn nilelsecontrol=control+1return control,control*controlendendfor i,j in square,9,0 doprint(i,j)end

表的基本

mytable = {}mytable[1] = "Lua"mytable[1] = nilmytable = nilmytable = {}print( type(mytable) )mytable[1] = "Lua"mytable["name"]="siki"newtable = mytableprint(newtable[1])print(mytable[1])newtable[1]="C#"print(newtable[1])print(mytable[1])newtable[2]="Java"print(mytable[2])mytable = nilprint(mytable.name)print(newtable.name)newtable = nil

表的基本操作

--方法一般都是 table.xxxxmethod--Table连接mytable = {"Lua","C#","Java","C++","C","abc","ABC"}print( table.concat(mytable) )print( table.concat(mytable,",") )print( table.concat(mytable,",",2,4) )--Table插入   mytable[6]="PHP"mytable[#mytable+1]="PHP"print(mytable[#mytable])table.insert( mytable,"Javascript" )print(mytable[#mytable])table.insert(mytable,2,"Boo")print(mytable[2],mytable[3])--Table移除mytable[2]=nilprint(mytable[2])table.remove(mytable,2)print(mytable[2])--Table排序mytable={34,32,34,2,45,45,435,6,4576,76,33,23,24,2343,21,2,2,2,2,2,2,2,2}print("排序前")for k,v in ipairs(mytable) doprint(k,v)endtable.sort(mytable)print("排序后")for k,v in ipairs(mytable) doprint(k,v)end--自定义最大值方法function get_max_number(tab)local mn = 0for k,v in pairs(tab) doif(mn<V) code="" thenmn="vendendreturn" mnendprint(="" get_max_number(mytable)="" )

模块

Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 。

module = {}module.var = "Name"module.func1 = function ()print("这个是Module里面的函数")endfunction module.func1()print("这个是Module里面的函数")endlocal function func2()print("这个是局部函数fun2")  --相当于一个私有函数 privateendfunction module.func3()func2()print("这个是全局函数func3")endreturn module

那么如何使用它呢:

--require "模块名"--require ("模块名")m = require "module"print(m.var)m.func1()m.func3()

元表(Metatable)

元表提供了让我们改变 table 的行为的能力,每个行为关联了对应的元方法,可理解为对表操作的扩展。

mytable = {"Lua","Java","C#","C++"} --普通表mymetatable = {} --元表   元表扩展了普通表的行为mytable =setmetatable(mytable,mymetatable)print( mytable[3] )print(getmetatable(mytable))print(mymetatable)tab = setmetatable({"Lua","Java","C#","C++"} , {__metatable="lock"} )print(getmetatable(tab))-- 使用__metatable可以保护元表,禁止用户访问元表中的成员或者修改元表。

__index 元方法

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

mytable = {"Lua","Java","C#","C++"}--__index 当访问到一个表里不存在的索引的时候 起作用mymetatable = {__index = function (tab,key)if(key>=10) thenreturn "Javascript"endend }mytable =setmetatable(mytable,mymetatable)print(mytable)print(mytable[1])print(mytable[9])

mytable = {"Lua","Java","C#","C++"}newtable = {seven="Javascript"}newtable[9]="C"mymetatable = {__index = newtable }mytable =setmetatable(mytable,mymetatable)print(mytable)print(mytable[1])print(mytable.seven)print(mytable[9])

__newindex 元方法

这个方法用来对表更新。当表设置了元方法 __newindex,在对新索引键赋值时,会调用元方法,而不进行赋值。而如果是对已存在的索引键,则会进行赋值,不调用元方法 __newindex。

mytable = {"Lua","Java","C#","C++"}mymetatable = {__newindex = function(tab,key,value)print("我们要修改的key为:"..key.." 把这个key值修改为:"..value)rawset(tab,key,value)end }mytable =setmetatable(mytable,mymetatable)mytable[1]="C#"mytable[5]="Lua"print(mytable[1])print(mytable[5])

mytable = {"Lua","Java","C#","C++"}newtable = {}mymetatable = {__newindex = newtable}mytable =setmetatable(mytable,mymetatable)mytable[1]="C#"mytable[5]="Lua"print(mytable[1])print(mytable[5])print(newtable[5])

为表添加操作符

相加操作,__add 操作符

mytable = {"Lua","Java","C#","C++"} --普通表mymetatable = {__add = function(tab,newtab)local mi = 0for k,v in pairs(tab)doif(k>mi) thenmi = kendendfor k,v in pairs(newtab) domi=mi+1table.insert(tab,mi,v)endreturn tabend} --元表   元表扩展了普通表的行为mytable =setmetatable(mytable,mymetatable)newtable = {"PHP","Python"}v=mytable+newtablev2=newtable + mytablefor k,v in pairs(v2) doprint(k,v)end

__call元方法

在表调用一个值时调用

mytable = {"Lua","Java","C#","C++","ccdd"} mymetatable = {__call = function (tab,arg1,arg2,arg3)print(arg1,arg2,arg3)return "MoGu"end,}mytable =setmetatable(mytable,mymetatable)v = mytable(123,34,453)print(v)

__tostring 元方法

用于修改表的输出行为,可以自定义表的输出内容 示例一:

mytable = {"Lua","Java","C#","C++","ccdd"} --普通表mymetatable = {__tostring = function (mytable)local str = ""for k,v in pairs(mytable) dostr = str..v..","endreturn strend}mytable =setmetatable(mytable,mymetatable)print(mytable)

示例二:

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

协同程序(coroutine)

--定义协同函数coroutine.create--启动协同函数coroutine.resume--暂停协同函数coroutine.yield--继续运行 coroutine.resume (不需要传递参数)co=coroutine.create(function (a,b)print(a+b)print(coroutine.status(co))print(a+b)print(coroutine.status(co))print( coroutine.running() )coroutine.yield(a*b,a/b)print(a-b)return a%b,a/b+1end)print( coroutine.running() )print(coroutine.status(co))res1,res2,res3 = coroutine.resume(co,10,40)print(res1,res2,res3)print(coroutine.status(co))print("I"m here!")res1,res2,res3 = coroutine.resume(co)print(res1,res2,res3)print(coroutine.status(co))--第一个yield的参数作为第一个resume的返回值--第一个resume的参数作为协程的参数, 第二个resume的参数作为第一个yield的返回值

function foo (a)    print("foo 函数输出", a)    return coroutine.yield(2 * a) -- 返回  2*a 的值end co = coroutine.create(function (a , b)    print("第一次协同程序执行输出", a, b) -- co-body 1 10    local r = foo(a + 1)         print("第二次协同程序执行输出", r)    local r, s = coroutine.yield(a + b, a - b)  -- a,b的值为第一次调用协同程序时传入         print("第三次协同程序执行输出", r, s)    return b, "结束协同程序"                   -- b的值为第二次调用协同程序时传入end)        print("main", coroutine.resume(co, 1, 10)) -- true, 4print("--分割线----")print("main", coroutine.resume(co, "r")) -- true 11 -9print("---分割线---")print("main", coroutine.resume(co, "x", "y")) -- true 10 endprint("---分割线---")print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutineprint("---分割线---")

Lua中文件的IO

简单模式:拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作。 完全模式:使用外部的文件句柄来实现。它以一种面向对象的形式,将所有的文件操作定义为文件句柄的方法。

打开文件操作语句如下: file = io.open (filename ,[ mode])

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

简单模式

-- 以只读方式打开文件file = io.open("data.lua", "r")-- 设置默认输入文件为 data.luaio.input(file)-- 输出文件第一行print(io.read())-- 关闭打开的文件io.close(file)-- 以附加的方式打开只写文件file = io.open("data.lua", "a")-- 设置默认输出文件为 data.luaio.output(file)-- 在文件最后一行添加 Lua 注释io.write("--  data.lua 文件末尾注释")-- 关闭打开的文件io.close(file)

file = io.open("data1.txt","w")io.output(file)io.write("www.runoob.com1\n")io.write("www.runoob.com2")io.write("www.runoob.com3")io.write("www.runoob.com4")io.close(file)file = io.open("data1.txt","r")io.input(file)print(io.read(10)) --读取一行\print(io.read(10)) --读取一行\print(io.read(10)) --读取一行\print(io.read(10)) --读取一行\print(io.read(10)) --读取一行\io.close(file)

完全模式

file=io.open("data1.txt","r")print(file:read())print(file:read())file:close()file=io.open("data1.txt","a")file:write("www.runoob.com5")file:close()

垃圾回收

Lua 提供以下函数collectgarbage ([opt [, arg]])用来控制自动内存管理:

collectgarbage(“collect”), 做一次完整的垃圾收集循环。通过参数 opt 它提供了一组不同的功能: collectgarbage(“count”),以 K 字节数为单位返回 Lua 使用的总内存数。 这个值有小数部分,所以只需要乘上 1024 就能得到 Lua 使用的准确字节数(除非溢出)。 collectgarbage(“restart”),重启垃圾收集器的自动运行。 collectgarbage(“setpause”),将 arg 设为收集器的 间歇率 (参见 §2.5)。 返回 间歇率 的前一个值。 collectgarbage(“setstepmul”),返回 步进倍率 的前一个值。 collectgarbage(“step”),单步运行垃圾收集器。 步长"大小"由 arg 控制。 传入 0 时,收集器步进(不可分割的)一步。 传入非 0 值, 收集器收集相当于 Lua 分配这些多(K 字节)内存的工作。 如果收集器结束一个循环将返回 true 。 collectgarbage(“stop”),停止垃圾收集器的运行。 在调用重启前,收集器只会因显式的调用运行。

mytable = {"apple", "orange", "banana"}print(collectgarbage("count"))mytable = nilprint(collectgarbage("count"))print(collectgarbage("collect"))print(collectgarbage("count"))

实现面向对象

--对于一个对象来说  属性 方法person ={name="MoGu",age=99 }person.eat = function ()print(person.name.."在吃饭")endfunction person.eat()print(person.name.."在吃饭")endperson.eat()

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

person ={name="MoGu",age=99 }person.eat = function (self)print(self.name.."在吃饭")endperson.eat(person)a = persona.eat(a)

通过 " : " 调用的时候,系统会自动传递当前的 table 给 self。

person ={name="MoGu",age=99 }function person:eat()print(self.name.."在吃饭")endperson:eat()a = persona:eat()

new 新对象

Person ={name="MoGu",age=99 }function Person:eat()print(self.name.."在吃饭")print(self.name.."的年龄是"..self.age)endfunction Person:new(o)local t = o or {}--调用一个属性的时候,如果 t 中不存在,那么会在 __index 所指定的 table 中查找 setmetatable( t, {__index=self })setmetatable(t,self)self.__index=selfreturn tendStudent = Person:new()Student.grade=1stu1 = Student:new()stu1:eat()print(stu1.grade)

责任编辑:

标签:

相关推荐:

精彩放送:

新闻聚焦
Top