该库提供了类型系统、常用容器、常用类库与异常处理等工具,拥有实用且轻量的工具可以轻量开发简单的程序,本着lua语言的定位,该库并不会增加更多繁重的内容,复杂功能推荐使用宿主语言实现。
- 拥有C#关键字与类型系统的Lua面向对象系统,拥有常用的容器、类库、try-catch异常处理等工具,更适用于熟悉.Net的Lua/Unity开发者。
- 本框架使用Pascal命名规则,核心级函数(关键字)为全小写,私有成员可以使用m_member或者__menmber来提醒其他开发者不要来使用该成员。
- 可以用于普通Lua开发或者嵌入其他程序中执行,可用于Unity开发。
- 推荐使用VSCode + EmmyLua插件进行开发,同时对VSCode的代码片段Snippets进行配置,可以达到同比VS的快速开发。
将SysLib文件夹放进你的工程目录
在使用之前(一般在程序入口处)使用require加载库,如:
SYSLIB_SIMPLENAME=truerequire"SysLib._include"其中SYSLIB_SIMPLENAME = true可以让该库中的类使用短名称,正常情况下使用类需要使用完全限定名如System.Collection.List.new(),如果在加载库前将该全局变量设置为true则可以使用短名称List.new()
类使用class.define关键字来继承,一个lua模块对应一个类,基类是可选的,如果不写则继承于SysLib.Object
class.define(类名, 基类)为了标识每个类的不同,可以采用路径全名的命名方式来声明。
localList, base=class.define("SysLib.Collections.List", Object)自定义类型声明
localTestClass, base=class.define("TestClass", Object)
--构造函数functionTestClass:constructor()
base.constructor(self)
Console.WriteLine("Hello World")
endreturnTestClass关于构造函数:
- 类型中使用constructor函数作为构造函数
- 如果一个类不存在一个构造函数则默认使用上一级基类的构造函数
- 如果一个类存在一个构造函数,并且基类非Object类型时,则需要满足基类的构造,在构造函数开始时使用
base.constructor(self, ...)进行基类的初始化
实例化
localtc=TestClass.new()或者
localtc=TestClass()如果给类型添加
支持type对比,gettype为本框架的类型获取关键字
tc:GetType() ==gettype(TestClass) -- true判断一个实例是否属于类型(包含派生):
istype(tc, gettype(TestClass)) --trueistype(tc, gettype(Object)) --trueistype(tc, gettype(Human)) --false或者使用Class而不是Type
instanceof(tc, TestClass) --trueinstanceof(tc, Object) --trueinstanceof(tc, Human) --false对继承类型判定
--确定 Type 是否派生自 Objectgettype(Type):IsSubclassOf(typeof(Object))支持Equals的重写的对比:
tc:Equals(target)Object静态方法,对比地址:
Object.Equals(tc, target)声明静态类
localManamger=class.static("Manamger")可以让字符串变量当做对象来使用,例如
localstr="Hello World"str:Replace("World", "God")
str:Length()
-- 获取字符串长度(包含中文等字符)str:CharLength()如果直接操作字符串则需要使用静态方法
localstr=String.Replace("Hello World", "World", "God")字符串构建 StringBuilder类
localsb=StringBuilder.new()
sb:Append("you")
sb:Append(" and ")
sb:Append("me")
sb:AppendLine("AppendLine")
sb:ToString()- BitMath类, And、Or、Xor、Not、LShift、RShift
lua中直接拿表当枚举类型,框架内只是提供了一些处理的方法,如Flag等。
AnimalType= {
Human=1,
Dog=2,
Cat=4,
Bird=8,
}- 按值获取枚举名
Enum.GetName(AnimalType, 2)
- 支持Flag(由位运算“或”驱动)
--C#: Animal animals = AnimalType.Dog | AnimalType.Cat;localanimals=Enum.NewFlag(AnimalType.Dog, AnimalType.Cat) localrst=Enum.HasFlag(animals, AnimalType.Dog)
---@classTestClasslocalTestClass, base=class.define("TestClass", Object)
functionTestClass:constructor(n1)
self.n=n1end---运算符重载functionTestClass.operatorAdd(target, target2)
returnTestClass.new(target.n+target2.n)
endreturnTestClass运算符重载直接在类中实现,可以搭配VSCode配置Snippets代码片段来达到使用VS的快速开发。 重载方法名有:
| 函数名 | 重载符号 |
|---|---|
| operatorAdd | + |
| operatorSub | - |
| operatorMul | * |
| operatorDiv | / |
| operatorEq | == |
| Invoke | () |
Convert类和对应类型的Parse方法
--基础类型转换localcint=Convert.ToInt("36.6")
localcint2=int.Parse("36.6")
localcnum=Convert.ToNumber("66.66")
localcnum=number.Parse("66.66")
localcstr=Convert.ToString(6666)
localcstr2=tostring(6666)
localcbol=Convert.ToBoolean("true")
localcbo2=Convert.ToBoolean("true")
localcbo3=bool.Parse("true")BitConverter
lua默认的迭代器只可以对table进行访问,但是该库的四大容器并不是直接储存在table中,这也是为了避免原方法被覆盖,所以可以使用each来遍历四大迭代器。
如果想继续使用lua原生迭代器,可以使用容器的GetEnumerator方法获取迭代器。
同样的,容器需要扩展时
常用的List和Dictionary实现了GetEnumerator方法,可以直接使用each迭代器,同时也支持lua原版的ipairs与pairs迭代器,并且容器拥有ForEach方法迭代器。
localarr=List.new()
arr:Add("苟利国家生死以")
arr:Add("岂因祸福避趋之")
--三种遍历方式 都可以-- 1.ForEach方法Console.WriteLine("ForEachMemberFunction:")
list:ForEach(function(item)
Console.WriteLine(item)
end)
-- 2.迭代器Console.WriteLine("Enumerator:")
forindex, valueinlist:GetEnumerator() doConsole.WriteLine(value)
end-- 3.或者使用eachConsole.WriteLine("Each:")
forindex, valueineach(list) doConsole.WriteLine(value)
endlocalfunctionTestFunction()
throw(ArgumentException.new("参数错误"))
-- throw(IOException.new("文件打开错误"))-- throw(IndexOutOfRangeException.new("下标越界"))-- throw(8)-- error("遇到了一个错误")endtry(function()
TestFunction()
end)
.catch(gettype(ArgumentException), function(_e)
---@typeArgumentExceptionlocale=_eConsole.WriteLine("ArgumentException")
Console.WriteLine(e:ToString())
end)
.catch(gettype(IOException), function(_e)
---@typeIOExceptionlocale=_eConsole.WriteLine("IOException")
Console.WriteLine(e:ToString())
end)
.catch(gettype(Exception), function(_e)
--捕捉所有框架类型的异常---@typeExceptionlocale=_eConsole.WriteLine("Exception")
Console.WriteLine(e:ToString())
end)
.catch(function(e)
--捕捉所有其他异常Console.WriteLine("other exception")
Console.WriteLine(tostring(e))
end)
.finally(function()
--无论是否发生异常该函数必定执行Console.WriteLine("finally function")
end)文件读写提供函数:
- File.ReadAllText(path)
- File.ReadAllLines(path)
- File.WriteAllText(path, content)
- File.WriteAllLines(path, contents)
- File.AppendAllText(path, content)
- File.AppendAllLines(path, contents)
- File.Exist(path)
- File.Copy(path, targetPath)
- File.Move(path, targetPath)
- File.Delete(path)
路径操作函数:
- Path.IsRootPath(path)
- Path.Combine(path1, path2)
- Path.GetDirectoryName(path)
- Path.GetExtension(path)
- Path.GetFileName(path)
- Path.GetFileNameWithoutExtension(path)
无实例的函数委托
localfunctionSetAge1(i)
Console.WriteLine("setAge1:", i)
endlocaldelegate=Delegate.new(nil, SetAge1)
--使用Invoke调用delegate:Invoke(2)有实例的函数委托
localTestObject=class.define("Test.TestObject", Object)
functionTestObject:SetNumber(i)
Console.WriteLine("SetNumber:", i)
endlocaltestObj=TestObject.new()
--提供实例localdeleg=Delegate.new(testObj, TestObject.SetNumber)
--不光可以使用Invoke,还可以直接用()deleg(5)事件采用多播委托的形式实现
localfunctionEventFun1()
Console.WriteLine("EventFun1")
endlocalfunctionEventFun2()
Console.WriteLine("EventFun2")
endlocalevent=Event.new()
event:Add(nil, EventFun1)
event:Add(Delegate.new(nil, EventFun2))
event:Invoke()引入库之后,既可使用单元测试模块:
单元测试以模块为单位,一个模块就是一项测试,一般测试放在Test文件夹中
if_DEBUGthenunittest({
require_test"Test.IOFileTest",
require_test"Test.IOPathTest",
require_test"Test.StringAndBuilderTest",
require_test"Test.EnumTest",
require_test"Test.DelegateEventsTest",
require_test"Test.ExceptionTest",
require_test"Test.OOPTest",
require_test"Test.BitConverterTest",
require_test"Test.Container.ListTest",
require_test"Test.Container.DictionaryTest",
require_test"Test.Container.StackTest",
require_test"Test.Container.QueueTest",
require_test"Test.SerializerTest",
})
end在进行单元测试时最好使用_DEBUG来确定是否执行。
- 序列化方法,将lua表转换为字符串,或将字符串反序列化为lua语句/表
- Lua表的拓展功能,数组拷贝、深拷贝等
- 序列化方法,将lua表转换为字符串,或将字符串反序列化为lua语句/表
- Lua表的拓展功能,数组拷贝、深拷贝等