lua基础
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命名规则(标识符)
- 不能以数字开头
- 不能是关键字
关键字比如:
- and
- break
- do
- else
- else
- if
- 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 表示执行的独立线路,用于执行协同程序
- table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。
在 Lua 中有一个 type 方法,它可以返回数据的类型,输出的是 string 字符串,比如:
print(type("Hello world")) --> string
print(type(10.4*3)) --> number
print(type(print)) --> function
print(type(type)) --> function
print(type(true)) --> boolean
print(type(nil)) --> nil
print(type(type(X))) --> string
nil 空类型
没有声明和赋值的变量都是默认 nil 类型
这个 nil 类型下面只有一个值 nil 值
把一个变量赋值为 nil,表示回收并删除这个变量
boolean 布尔类型
这个下面只有两个值 true 和 false
false 和 nil 都代表 false,其他任何值都代表 true(0和空字符串 Lua 也都认为是 true)
number数字类型
- 数字的表示方式
4 0.4 4.45e-3 0.3e12 5E+20 - 整数和小数都是 number 类型的
type(3) type(3.5) - 如果整数和小数的大小是一样的,那么 Lua 认为就是相等的
1 == 1.0 -3 == -3.0 0.2e3==200 - 如果我们想要区分整数和小数这两种类型,可以使用 math.type 函数
math.type(3) math.type(3.0) integer float - 1e3 表示一个小数
1000.0 - 支持16进制
0xff 0x1A3 0x0.2
string字符串类型
定义:使用单引号或者双引号表示字符串
- 替换字符串
a="one string";
b=string.gsub(a,"one","another")
print(a) --> one string
print(b) --> another string
- 取得字符串的长度#
print(#a) --> 10
print(#"good bye") --> 8
- 字符串组拼
"Hello".."World"
"result is"..3
table表类型
表在 Lua 中是一个非常重要的数据结构,也是最有权力的。
- 我们可以使用表表示数组,集合,字典…
- Lua table 使用关联型数组,你可以用任意类型的值来作数组的索引,但这个值不能是 nil。
- Lua table 是不固定大小的,你可以根据自己需要进行扩容。
- 表既不是值类型也不是变量,它是对象。
- 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 then
return n;
else
return n*fact(n-1);
end
end
print(fact(3))
print(fact(5))
fact2 = fact
print(fact2(5))
另一种,关于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
);
执行结果为:
key1 = val1
key2 = 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 = 10
print(b)
function test()
c = 5
local d = 6
end
test()
print(c,d)
do
local a = 10
b =11
print(a,b)
end
print(a,b)
多变量赋值
a,b = 10,20 -- a = 10 b = 20
a,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 --没有值赋值 nil
print(a,b,c)
function test()
return 40,50
end
a,b = test() --返回多个值 并获取
print(a,b)
循环
1,while循环
2,for循环
3,repeat unitl (do while)
while循环
while (condition)
do
statements
end
a = 1
while (a<=20)
do
if (a%2==1) then
print(a)
end
a=a+1
end
for循环
1,数值for循环
for var=start,end,step do
循环体
end
这里var会从start变化到end,每次变化一step进行
for i=1,10,2 do
print(i)
end
for i=20,1,-3 do
print(i)
end
2,泛型for循环
tab1 = {key1="value1",key2="value2"}
for k,v in pairs(tab1) do
print(k,v)
end
tab2 = {"apple","橡胶","西瓜","猕猴桃"}
for k,v in pairs(tab2) do
print(k,v)
end
repeat until循环
repeat
循环体
until(condition)
a = 1
repeat
print(a)
a=a+1
until(a>10)
循环嵌套
for i=1,10 do
for j=1,i do
print(i)
end
end
for i=1,10 do
j=1
while j<=i do
print(i)
j=j+1
end
end
流程控制
if (布尔表达式) then
为true的时候要执行的代码
end
if(布尔表达式)then
为true的时候要执行的代码
else
为false的时候要执行的代码
end
if (布尔表达式) then
//1
elseif (布尔表达式) then
//2
else
//3
end
-----
if (0) then
print(0)
end
-----
a = 10
if (a>10) then
print("a大于10")
end
-----
if a<=10 then
print("a小于等于10")
end
-----
if (b) then
print("b不为空")
else
print("b为空")
end
-----
a = 100
if (a<=50) then
print("a<=50")
elseif (a<=100) then
print("a<=100")
elseif (a<=150) then
print("a<=150")
else
print("上面三种情况都不满足")
end
function用法特性总结
[local] function functionName(arg1,arg2,arg3…argn)
functionBody
[return value1,value2…valuen]
end
local function max(num1,num2)
if(num1>num2)then
return num1
else
return num2
end
end
print( max(1,10) )
--函数可以作为数据赋值 可以作为参数传递
temp = max
print(temp(40,3))
-----
myprint = function (param)
print("这个是我的打印函数"..param)
end
myprint(100)
-----
function add(num1,num2,printFun)
local res = num1+num2
printFun(res)
end
add(40,50,myprint)
--lua里面的函数可以返回多个值
可变参数 用 ... 三个点表示
function average(...)
local arg = {...}
res = 0
for k,v in pairs(arg) do
res = res+v
end
-- #arg 取得参数的个数 #"hello"
print(res/#arg)
end
average(10)
average(1,30)
average(3,8,90)
average(5,67,7,8,3)
运算符
算术运算符:+ - * / % ^求幂 -
关系运算符: == ~= > < >= <=
if(a==b)then
print("a==b")
else
print("a~=b")
end
-----
if(a~=b)then
print("ab不相等")
else
print("ab相等")
end
-----
if(a<b)then
print("a小于b")
else
print("a不小于b")
end
逻辑运算符 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 = 5
num2 = 10
print(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 = 2014
print(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+") do
print(word)
end
数组
Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。
array = {"Lua","C#"}
array[3]="Java"
for i=1,3 do
print(array[i])
end
array = {}
for i =-2,2 do
array[i]=i*3
end
for i=-2,2 do
print(array[i])
end
二维…多维数组
array = { {"小明","小红"},{"小刘","小狼"},{"大明","大刘"},{"小赵","李四"} } --4*2
print(array[3][1])
for i =1,4 do
for j=1,2 do
print(array[i][j])
end
end
array = {{},{},{}}
for i = 1,3 do
array[i]={}
for j=1,2 do
array[i][j]=i*j
end
end
for i = 1,3 do
for j=1,2 do
print(array[i][j])
end
end
迭代器
pairs迭代table,遍历表中所有的key跟value
ipars按照索引从1开始,递增遍历,遇到nil值就停止
array = {"Lua","C#","Java"}
for k in pairs(array) do
print(k,v)
end
array[2]=nil
for k,v in ipairs(array) do
print(k,v)
end
整体的结构
for 变量列表 in 迭代函数,状态变量,控制变量 do
--循环体
end
1,调用迭代函数,(把状态变量和控制变量当做参数传递给迭代函数) 状态变量只会在第一次调用的时候赋值。
2,如果迭代函数的返回值为nil,退出for循环;如果不是nil的话,把返回值赋值给变量列表,并执行循环体。
自定义迭代函数,求平方
function square(state,control)
if(control>=state) then
return nil
else
control=control+1
return control,control*control
end
end
for i,j in square,9,0 do
print(i,j)
end
表
表的基本
mytable = {}
mytable[1] = "Lua"
mytable[1] = nil
mytable = nil
mytable = {}
print( type(mytable) )
mytable[1] = "Lua"
mytable["name"]="siki"
newtable = mytable
print(newtable[1])
print(mytable[1])
newtable[1]="C#"
print(newtable[1])
print(mytable[1])
newtable[2]="Java"
print(mytable[2])
mytable = nil
print(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]=nil
print(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) do
print(k,v)
end
table.sort(mytable)
print("排序后")
for k,v in ipairs(mytable) do
print(k,v)
end
--自定义最大值方法
function get_max_number(tab)
local mn = 0
for k,v in pairs(tab) do
if(mn<v) then
mn=v
end
end
return mn
end
print( get_max_number(mytable) )
模块
Lua 的模块是由变量、函数等已知元素组成的 table,因此创建一个模块很简单,就是创建一个 table,然后把需要导出的常量、函数放入其中,最后返回这个 table 。
module = {}
module.var = "Name"
module.func1 = function ()
print("这个是Module里面的函数")
end
function module.func1()
print("这个是Module里面的函数")
end
local function func2()
print("这个是局部函数fun2") --相当于一个私有函数 private
end
function module.func3()
func2()
print("这个是全局函数func3")
end
return 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) then
return "Javascript"
end
end
}
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 = 0
for k,v in pairs(tab)do
if(k>mi) then
mi = k
end
end
for k,v in pairs(newtab) do
mi=mi+1
table.insert(tab,mi,v)
end
return tab
end
} --元表 元表扩展了普通表的行为
mytable =setmetatable(mytable,mymetatable)
newtable = {"PHP","Python"}
v=mytable+newtable
v2=newtable + mytable
for k,v in pairs(v2) do
print(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) do
str = str..v..","
end
return str
end
}
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+1
end
)
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, 4
print("--分割线----")
print("main", coroutine.resume(co, "r")) -- true 11 -9
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- true 10 end
print("---分割线---")
print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
print("---分割线---")
Lua中文件的IO
简单模式:拥有一个当前输入文件和一个当前输出文件,并且提供针对这些文件相关的操作。
完全模式:使用外部的文件句柄来实现。它以一种面向对象的形式,将所有的文件操作定义为文件句柄的方法。
打开文件操作语句如下:
file = io.open (filename ,[ mode])
模式诸如以下这些:
r,以只读方式打开文件,该文件必须存在。
w,打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
a,以附加的方式打开只写文件。若文件不存在,建立该文件,如果存在,写入的数据会被加到文件尾,即原先的内容会保留。
r+,以可读写方式打开文件,该文件必须存在。
w+,打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a+,与a类似,但此文件可读可写
b,二进制模式,如果文件是二进制文件,可以加上b
+,号表示对文件既可以读也可以写
简单模式
-- 以只读方式打开文件
file = io.open("data.lua", "r")
-- 设置默认输入文件为 data.lua
io.input(file)
-- 输出文件第一行
print(io.read())
-- 关闭打开的文件
io.close(file)
-- 以附加的方式打开只写文件
file = io.open("data.lua", "a")
-- 设置默认输出文件为 data.lua
io.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 = nil
print(collectgarbage("count"))
print(collectgarbage("collect"))
print(collectgarbage("count"))
实现面向对象
--对于一个对象来说 属性 方法
person ={ name="MoGu",age=99 }
person.eat = function ()
print(person.name.."在吃饭")
end
function person.eat()
print(person.name.."在吃饭")
end
person.eat()
通过 “·” 来调用方法的时候,self 不会自动赋值,我们必须通过第一个参数来传递当前的 table。
person ={ name="MoGu",age=99 }
person.eat = function (self)
print(self.name.."在吃饭")
end
person.eat(person)
a = person
a.eat(a)
通过 " : " 调用的时候,系统会自动传递当前的 table 给 self。
person ={ name="MoGu",age=99 }
function person:eat()
print(self.name.."在吃饭")
end
person:eat()
a = person
a:eat()
new 新对象
Person ={ name="MoGu",age=99 }
function Person:eat()
print(self.name.."在吃饭")
print(self.name.."的年龄是"..self.age)
end
function Person:new(o)
local t = o or {}
--调用一个属性的时候,如果 t 中不存在,那么会在 __index 所指定的 table 中查找 setmetatable( t, { __index=self })
setmetatable(t,self)
self.__index=self
return t
end
Student = Person:new()
Student.grade=1
stu1 = Student:new()
stu1:eat()
print(stu1.grade)
Lua编程基础:轻量脚本语言与实战应用
1848

被折叠的 条评论
为什么被折叠?



