标签: Lua #Lua starter Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。html
##Lua 应用场景 游戏开发 独立应用脚本 Web 应用脚本 扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench 安全系统,如入侵检测系统shell
##Hello world!数据库
print("Hello World")
##注释数组
--行注释 --[[ 块注释 --]]
##变量 ###全局变量 *默认即为全局变量,无需声明符号 *访问未定义的全局变量不出错 *删除全局变量将其赋值为nil(等同于其余语言NULL)便可安全
a=10 --全局变量 print(a) --10 a=nil --删除该变量 print(a) --nil
###局部变量数据结构
local data = 100; local function fun1() print(data); data = data+50; end data = 200; local data = 300; -- 从新定义一个局部变量 local function fun2() print(data); data = data+50; end data = 400; --调用 fun1(); -- 200 fun2(); -- 400 fun1(); -- 250 fun2(); -- 450
###赋值闭包
a, b = 10, 2*x x, y = y, x -- swap 'x' for 'y' a[i], a[j] = a[j], a[i] -- swap 'a[i]' for 'a[i]' -[[赋值多个的时候,以下规则 a. 变量个数 > 值的个数 按变量个数补足nil b. 变量个数 < 值的个数 多余的值会被忽略 ]] a, b, c = 0, 1 print(a,b,c) --> 0 1 nil a, b = a+1, b+1, b+2 -- value of b+2 is ignored print(a,b) --> 1 2 a, b, c = 0 --> 易错!注意!!! print(a,b,c) --> 0 nil nil
###索引app
t[i] t.i -- 当索引为字符串类型时的一种简化写法 gettable_event(t,i) -- 采用索引访问本质上是一个相似这样的函数调用
##数据类型 | 类型 | 说明 | | -------- | -----: | | nil | 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中至关于false)。| | boolean | 包含两个值:false和true。| | number | 表示双精度类型的实浮点数| | string | 字符串由一对双引号或单引号来表示| | function | 由 C 或 Lua 编写的函数| | userdata | 表示任意存储在变量中的C数据结构| | thread | 表示执行的独立线路,用于执行协同程序| | table Lua | 中的表(table)实际上是一个"关联数组"(associative arrays),数组的索引能够是数字或者是字符串。在 Lua 里,table 的建立是经过"构造表达式"来完成,最简单构造表达式是{},用来建立一个空表。|ide
--可用type查看类型 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 值:函数
print(type(a)) -- nil
对于全局变量和 table,nil 还有一个"删除"做用,给全局变量或者 table 表里的变量赋一个 nil 值,等同于把它们删掉,执行下面代码就知:
tab1 = { key1 = "val1", key2 = "val2", "val3" } for k, v in pairs(tab1) do print(k .. " - " .. v) end tab1.key1 = nil for k, v in pairs(tab1) do print(k .. " - " .. v) --不会打印key1了 end
###bool类型
print(type(true)) print(type(false)) print(type(nil)) if false or nil then print("至少有一个是 true") else print("false 和 nil 都为 false!") --false 和 nil 都为 false! end
###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))
###string
string1 = "this is string1" --[[能够输出换行的string]] html = [[ <html> <head></head> <body> <a href="http://www.w3cschool.cc/">w3cschool菜鸟教程</a> </body> </html> ]] print(html) --算数操做Lua尝试转换为number进行操做 print("1"+2) --3.0 --字符串链接用.. print("1".."2") --12 --符号#可计算字符串长度 print(#html)
###table(表)
-- 建立一个空的 table local tbl1 = {} -- 直接初始表 index由1开始 local tbl2 = {"apple", "pear", "orange", "grape"} for key, val in pairs(tbl2) do print("Key", key, val) end a = {} a["key"] = "value" --保存一个键值对 "key":"value" key = 10 a[key] = 22 --10:22 a[key] = a[key] + 11 for k, v in pairs(a) do --两个键值对 print(k .. " : " .. v) end
a3 = {} for i = 1, 10 do a3[i] = i end a3["key"] = "val" print(a3["key"]) --val print(a3["none"]) --nil
###function(函数)
function factorial1(n) if n == 0 then return 1 else return n * factorial1(n - 1) end end print(factorial1(5)) factorial2 = factorial1 print(factorial2(5))
function anonymous(tab, fun) for k, v in pairs(tab) do print(fun(k, v)) end end tab = { key1 = "val1", key2 = "val2" } anonymous(tab, function(key, val) return key .. " = " .. val end)
###thread(线程) 在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差很少,拥有本身独立的栈、局部变量和指令指针,能够跟其余协同程序共享全局变量和其余大部分东西。 线程跟协程的区别:线程能够同时多个运行,而协程任意时刻只能运行一个,而且处于运行状态的协程只有被挂起(suspend)时才会暂停。
###userdata(自定义类型)
userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所建立的类型,能够将任意 C/C++ 的任意数据类型的数据(一般是 struct 和 指针)存储到 Lua 变量中调用。
##循环 ###while
a=10 while( a < 20 ) do print("a 的值为:", a) a = a+1 end
###for
for var=exp1,exp2,exp3 do <执行体> end --var从exp1变化到exp2,每次变化以exp3为步长递增var,并执行一次"执行体"。exp3是可选的,若是不指定,默认为1。 --eg. for i=1,f(x) do --此处的f(x)只会在初始化循环时候执行一次 print(i) end for i=10,1,-1 do print(i) end --f(x)的例子 function f(x) print("function") return x*2 end for i=1,f(5) do print(i) end --[[ function 1 2 3 4 5 6 7 8 9 10 --]]
###泛型for循环
--打印数组a的全部值 a = {"Lua", "Tutorial"} for i,v in ipairs(a) do print(i..v) end --i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组。
###repeat...until(相似do while)
--[ 变量定义 --] a = 10 --[ 执行循环 --] repeat print("a的值为:", a) a = a + 1 until( a > 15 )
###不一样循环能够嵌套
j =2 for i=2,10 do for j=2,(i/j) , 2 do if(not(i%j)) then break end if(j > (i/j))then print("i 的值为:",i) end end end
###break
--[ 定义变量 --] a = 10 --[ while 循环 --] while( a < 20 ) do print("a 的值为:", a) a=a+1 if( a > 15) then --[ 使用 break 语句终止循环 --] break end end
##流程控制
--[ 定义变量 --] a = 100 --[ 检查布尔条件 --] if( a == 10 ) then --[ 若是条件为 true 打印如下信息 --] print("a 的值为 10" ) else if( a == 20 ) then --[ if else if 条件为 true 时打印如下信息 --] print("a 的值为 20" ) else if( a == 30 ) then --[ if else if condition 条件为 true 时打印如下信息 --] print("a 的值为 30" ) else --[ 以上条件语句没有一个为 true 时打印如下信息 --] print("没有匹配 a 的值" ) end print("a 的真实值为: ", a )
##函数
--实例 --[[ 函数返回两个值的最大值 --]] function max(num1, num2) if (num1 > num2) then result = num1; else result = num2; end return result; end -- 调用函数 print("两值比较最大值为 ",max(10,4)) print("两值比较最大值为 ",max(5,6))
###函数做为参数
myprint = function(param) print("这是打印函数 - ##",param,"##") end function add(num1,num2,functionPrint) result = num1 + num2 -- 调用传递的函数参数 functionPrint(result) end myprint(10) -- myprint 函数做为参数传递 add(2,5,myprint)
###多返回值
s, e = string.find("w3cschool菜鸟教程:www.w3cschool.cc", "菜鸟教程") print(s,e)
function maximum (a) local mi = 1 -- 最大值索引 local m = a[mi] -- 最大值 for i,val in ipairs(a) do if val > m then mi = i m = val end end return m, mi end print(maximum({8,10,23,12,5}))
###可变参数
function average(...) result = 0 local arg={...} for i,v in ipairs(arg) do result = result + v end --#arg 表示传入参数的个数 print("总共传入 " .. #arg .. " 个数") return result/#arg end print("平均值为",average(10,5,3,4,5,6))
##运算符 ###算数
a = 21 b = 10 c = a + b print("Line 1 - c 的值为 ", c ) c = a - b print("Line 2 - c 的值为 ", c ) c = a * b print("Line 3 - c 的值为 ", c ) c = a / b print("Line 4 - c 的值为 ", c ) c = a % b print("Line 5 - c 的值为 ", c ) c = a^2 print("Line 6 - c 的值为 ", c ) c = -a print("Line 7 - c 的值为 ", c ) --[[ Line 1 - c 的值为 31 Line 2 - c 的值为 11 Line 3 - c 的值为 210 Line 4 - c 的值为 2.1 Line 5 - c 的值为 1 Line 6 - c 的值为 441 Line 7 - c 的值为 -21 --]]
###关系
a = 21 b = 10 if( a == b ) then print("Line 1 - a 等于 b" ) else print("Line 1 - a 不等于 b" ) end if( a ~= b ) then print("Line 2 - a 不等于 b" ) else print("Line 2 - a 等于 b" ) end if ( a < b ) then print("Line 3 - a 小于 b" ) else print("Line 3 - a 大于等于 b" ) end if ( a > b ) then print("Line 4 - a 大于 b" ) else print("Line 5 - a 小于等于 b" ) end -- 修改 a 和 b 的值 a = 5 b = 20 if ( a <= b ) then print("Line 5 - a 小于等于 b" ) end if ( b >= a ) then print("Line 6 - b 大于等于 a" ) end
###逻辑
a = true b = true if ( a and b ) then print("a and b - 条件为 true" ) end if ( a or b ) then print("a or b - 条件为 true" ) end print("---------分割线---------" ) -- 修改 a 和 b 的值 a = false b = true if ( a and b ) then print("a and b - 条件为 true" ) else print("a and b - 条件为 false" ) end if ( not( a and b) ) then print("not( a and b) - 条件为 true" ) else print("not( a and b) - 条件为 false" ) end
###特殊
a = "Hello " b = "World" print("链接字符串 a 和 b ", a..b ) print("b 字符串长度 ",#b ) print("字符串 Test 长度 ",#"Test" ) print("w3cschool菜鸟教程网址长度 ",#"www.w3cschool.cc" )
##字符串 ###示例
string1 = "Lua" print("\"字符串 1 是\"",string1) string2 = 'w3cschool.cc' print("字符串 2 是",string2) string3 = [["Lua 教程"]] print("字符串 3 是",string3)
###字符串经常使用操做
--转大写 print(string.upper("abc")) --转小写 print(string.upper("ABC")) --替换字符串 数字表示替换次数,忽略则所有替换 print(string.gsub("abcabc",'c','d',1)) --字符串查找 数字为起始位置,找到则返回起止位置 print(string.find("abcabc",'a',3)) --字符串反转 print(string.reverse("12345")) --格式化字符串 string.format("the value is:%d",4) --数字转换为字符串并链接 print(string.char(97,98,99,100)) --byte转换为整数,可指定位置,默认为1 print(string.byte("abc",2)) --计算长度 同#"string" print(string.len("abc")==#"abc") --返回字符串的n个拷贝 print(string.rep('a', 3)) --链接字符串 print("aaa"..'bbb')
##数组 ###一维
array = {"Lua", "Tutorial"} --Lua 索引值是以 1 为起始,但你也能够指定 0 开始。 for i= 0, 2 do print(array[i]) end --也能够用负数做为索引 array = {} for i= -2, 2 do array[i] = i *2 end for i = -2,2 do print(array[i]) end
###多维
-- 初始化数组 array = {} for i=1,3 do array[i] = {} for j=1,3 do array[i][j] = i*j end end -- 访问数组 for i=1,3 do for j=1,3 do print(array[i][j]) end end
##迭代器 ###内置简单迭代
array = {"Lua", "Tutorial"} for key,value in ipairs(array) do print(key, value) end
###自定义的迭代器
function square(iteratorMaxCount,currentNumber) if currentNumber<iteratorMaxCount then currentNumber = currentNumber+1 return currentNumber, currentNumber*currentNumber end end for i,n in square,4,0 do print(i,n) end
###利用闭包实现的迭代器
array = {"Lua", "Tutorial"} function elementIterator (collection) local index = 0 local count = #collection -- 闭包函数 return function () index = index + 1 if index <= count then -- 返回迭代器的当前元素 return collection[index] end end end for element in elementIterator(array) do print(element) end
##Lua table
###初始化与销毁
-- 初始化表 mytable = {} -- 指定值 mytable[1]= "Lua" -- 移除引用 mytable = nil -- lua 垃圾回收会释放内存
###table的引用(相似Java)
-- 简单的 table 演示table类型的引用相似Java mytable = {} print("mytable 的类型是 ",type(mytable)) mytable[1]= "Lua" mytable["wow"] = "修改前" print("mytable 索引为 1 的元素是 ", mytable[1]) print("mytable 索引为 wow 的元素是 ", mytable["wow"]) -- alternatetable和mytable的是指同一个 table alternatetable = mytable print("alternatetable 索引为 1 的元素是 ", alternatetable[1]) print("mytable 索引为 wow 的元素是 ", alternatetable["wow"]) alternatetable["wow"] = "修改后" print("mytable 索引为 wow 的元素是 ", mytable["wow"]) -- 释放变量 alternatetable = nil print("alternatetable 是 ", alternatetable) -- mytable 仍然能够访问 print("mytable 索引为 wow 的元素是 ", mytable["wow"]) mytable = nil print("mytable 是 ", mytable)
###table操做
--链接table中的全部元素,利用分隔符 t1={"a","b","c"} print(table.concat(t1)) print(table.concat(t1,"@@")) print(table.concat(t1,"@@",1,2)) --插入元素 table.insert(t1,"d") print(t1[4]) table.insert(t1,2,"b") print(t1[2]) --删除元素 print("当前元素:"..table.concat(t1,",")) table.remove(t1) print("remove(t1)默认删除最后一个元素,当前元素:"..table.concat(t1,",")) table.remove(t1,1) print("remove(t1,1)以后"..table.concat(t1,",")) --排序 t1={"c","b","a"} print("排序前:"..table.concat(t1,",")) table.sort(t1) print("排序后:"..table.concat(t1,","))
###!!!慎用"#table"
tbl = {"a", "b","c"} print("tbl 长度 ", #tbl) --3 tbl = {"a", "b","c"="bb"} print("tbl 长度 ", #tbl) --2 tbl = {"a", "b",nil} print("tbl 长度 ", #tbl) --2 tbl = {"a", nil,"b",nil} --1 print("tbl 长度 ", #tbl)
##模块与包 ###自定义包
-- 文件名为 module.lua -- 定义一个名为 module 的模块 module = {} -- 定义一个常量 module.constant = "这是一个常量" -- 定义一个函数 function module.func1() io.write("这是一个公有函数!\n") end local function func2() print("这是一个私有函数!") end function module.func3() func2() end return module
--使用自定义包 require("module") print(module.constant) module.func3() --设置别名 local m = require("module") print(m.constant) m.func3()
###加载策略
#LUA_PATH export LUA_PATH="~/lua/?.lua;;"
##元表
--__index元方法查看表中元素是否存在,若是不存在,返回结果为nil;若是存在则由__index 返回结果。 mytable = setmetatable({key1 = "value1"}, { __index = function(mytable, key) if key == "key2" then return "metatablevalue" else return mytable[key] end end }) print(mytable.key1,mytable.key2)
###__newindex
--当你给表的一个缺乏的索引赋值,解释器就会查找__newindex元方法:若是存在则调用这个函数而不进行赋值操做。 mymetatable = {} mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable }) print(mytable.key1) mytable.newkey = "新值2" print(mytable.newkey,mymetatable.newkey) mytable.key1 = "新值1" print(mytable.key1,mymetatable.key1) mytable = setmetatable({key1 = "value1"}, { __newindex = function(mytable, key, value) rawset(mytable, key, "\""..value.."\"") end }) --使用rawset 函数来更新表 mytable.key1 = "new value" mytable.key2 = 4 print(mytable.key1,mytable.key2)
###__add
--为表添加操做符 -- 自定义计算表中最大值函数 table_maxn function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 两表相加操做(合并) mytable = setmetatable({ 1, 2, 3 }, { __add = function(mytable, newtable) for i = 1, table_maxn(newtable) do table.insert(mytable, table_maxn(mytable)+1,newtable[i]) end return mytable end }) secondtable = {4,5,6} mytable = mytable + secondtable for k,v in ipairs(mytable) do print("index:"..k,v) end --[[ __add 对应的运算符 '+'. __sub 对应的运算符 '-'. __mul 对应的运算符 '*'. __div 对应的运算符 '/'. __mod 对应的运算符 '%'. __unm 对应的运算符 '-'. __concat 对应的运算符 '..'. __eq 对应的运算符 '=='. __lt 对应的运算符 '<'. __le 对应的运算符 '<='. --]]
###__call
--__call元方法 -- 计算表中最大值,table.maxn在Lua5.2以上版本中已没法使用 -- 自定义计算表中最大值函数 table_maxn function table_maxn(t) local mn = 0 for k, v in pairs(t) do if mn < k then mn = k end end return mn end -- 定义元方法__call mytable = setmetatable({10}, { __call = function(mytable, newtable) sum = 0 for i = 1, table_maxn(mytable) do sum = sum + mytable[i] end for i = 1, table_maxn(newtable) do sum = sum + newtable[i] end return sum end }) newtable = {10,20,30} print(mytable(newtable))
###__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)
##协同(coroutine)
--协程 -- coroutine_test.lua 文件 --create建立一个协程,未调用以前为阻塞状态 --此时co是协程对象 co = coroutine.create( function(i) print(i); end ) print(coroutine.status(co)) -- suspended --与create配合使用唤醒协程进行传参 coroutine.resume(co, 1) -- 1 print(coroutine.status(co)) -- dead print("----------") --wrap返回一个函数a,调用a()则进入协程并传递参数 --此时co表示一个函数 co = coroutine.wrap( function(i) print(i); end ) co(1) print("----------") co2 = coroutine.create( function() for i=1,10 do print(i) if i == 3 then print(coroutine.status(co2)) --running print(coroutine.running()) --返回正在运行的线程号 thread:XXXXXX end coroutine.yield()--挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有不少有用的效果 end end ) coroutine.resume(co2) --1 coroutine.resume(co2) --2 coroutine.resume(co2) --3 print(coroutine.status(co2)) -- suspended print(coroutine.running()) print("----------")
###resume与create的配合 注意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 --第二次唤醒协同程序,参数传递给上一次的yield() line:3 print("main", coroutine.resume(co, "r")) -- true 11 -9 --第三次唤醒协同程序,参数传递给上一次的yield() line:11 print("main", coroutine.resume(co, "x", "y")) -- true 10 end print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine
###生产者-消费者
local newProductor function productor() local i = 0 while true do i = i + 1 send(i) -- 将生产的物品发送给消费者 end end function consumer() while true do local i = receive() -- 从生产者那里获得物品 print(i) end end function receive() local status, value = coroutine.resume(newProductor) return value end function send(x) coroutine.yield(x) -- x表示须要发送的值,值返回之后,就挂起该协同程序 end -- 启动程序 newProductor = coroutine.create(productor) consumer()
##IO
###简单模式(类c语言)
--lua文件IO简单模式 相似c语言 --[[ file = io.open (filename [, mode]) r 以只读方式打开文件,该文件必须存在。 w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则创建该文件。 a 以附加的方式打开只写文件。若文件不存在,则会创建该文件,若是文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留) r+ 以可读写方式打开文件,该文件必须存在。 w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则创建该文件。 a+ 与a相似,但此文件可读可写 b 二进制模式,若是文件是二进制文件,能够加上b + 号表示对文件既能够读也能够写 --]] -- -- 以只读方式打开文件 file = io.open("test.txt", "r") -- 设置默认输入文件为 test.lua io.input(file) -- 读取一个数字 print(io.read("*n")) -- 读取n个字符 print(io.read(2)) -- 输出文件下一行 默承认不写,当前位置读取至换行止 print(io.read("*l")) -- 从当前位置读取整个文件 print(io.read("*a")) -- 关闭打开的文件 io.close(file) -- 以附加的方式打开只写文件 file = io.open("test.lua", "a") -- 设置默认输出文件为 test.lua io.output(file) -- 在文件最后一行添加 Lua 注释 io.write("-- test.lua 文件末尾注释") -- 关闭打开的文件 io.close(file)
####其余的IO函数
###彻底模式 IO.xxx变为file.xxx
-- 以只读方式打开文件 file = io.open("test.lua", "r") -- 输出文件第一行 print(file:read()) -- 关闭打开的文件 file:close() -- 以附加的方式打开只写文件 file = io.open("test.lua", "a") -- 在文件最后一行添加 Lua 注释 file:write("--test") -- 关闭打开的文件 file:close()
-- 以只读方式打开文件 file = io.open("test.lua", "r") -- 从倒数25位置开始读取整个文件内容 file:seek("end",-25) print(file:read("*a")) -- 关闭打开的文件 file:close()
for line in io.lines("test.lua") do print(line) end
##错误处理 ###assert与error
local function add(a,b) assert(type(a) == "number", "a is not a number") assert(type(b) == "number", "b is not a number") if(a==b) then -- error终止正在执行的函数,返回message,第二个参数为0,1,2 -- 表示0:不添加错误位置信息;1(默认):调用error位置(文件+行号) -- 2:指出哪一个调用error的函数的函数 error("err",2) end return a+b end print(add(10,20))
###pcall与xpcall
--pcall表示保护模式运行程序,第一个参数为函数,第二个参数为函数的参数 pcall(function(i) print(i) end, aa==1) --无错误返回true,有错误返回false,err_info has_err,err_info=pcall(function(i) print(i) error('error..') end, 33) print(has_err,err_info) --xpcall提供更详细的信息 function myfunction () n = n/nil end function myerrorhandler( err ) print( "ERROR:", err ) end status = xpcall( myfunction, myerrorhandler ) print( status)
##垃圾回收 lua为自动垃圾回收
##面向对象
-- 面向对象,使用table模拟实现 -- Meta class Shape = {area = 0} -- 基础类方法 new function Shape:new (o,side) o = o or {} -- self相似this setmetatable(o, self) self.__index = self side = side or 0 self.area = side*side; return o end -- 基础类方法 printArea function Shape:printArea () print("面积为 ",self.area) end -- 建立对象 myshape = Shape:new(nil,10) myshape:printArea()
###继承与方法重写
-- Meta class Shape = {area = 0} -- 基础类方法 new function Shape:new (o,side) o = o or {} setmetatable(o, self) self.__index = self side = side or 0 self.area = side*side; return o end -- 基础类方法 printArea function Shape:printArea () print("面积为 ",self.area) end -- 建立对象 myshape = Shape:new(nil,10) myshape:printArea() Square = Shape:new() -- 派生类方法 new function Square:new (o,side) o = o or Shape:new(o,side) setmetatable(o, self) self.__index = self return o end -- 派生类方法 printArea 重写 function Square:printArea () print("正方形面积为 ",self.area) end -- 建立对象 mysquare = Square:new(nil,10) mysquare:printArea() Rectangle = Shape:new() -- 派生类方法 new function Rectangle:new (o,length,breadth) o = o or Shape:new(o) setmetatable(o, self) self.__index = self self.area = length * breadth return o end -- 派生类方法 printArea function Rectangle:printArea () print("矩形面积为 ",self.area) end -- 建立对象 myrectangle = Rectangle:new(nil,10,20) myrectangle:printArea()