lua入门的系列文章于2019年初诞生于陌陌公司内部的文档系统,目的是为部门内部的lua新人培训而做。2020年疫情期间想做些mln的推广,便转至公众号。佛系一段时间后觉得公众号受众面比较窄,遂转移至csdn,希望能帮助更多的人快速了解和掌握MLN这一跨平台技术。因都是本人所作,故打上了原创标签。
以下正文:
Lua是用C编写的一个小巧轻量级的脚本语言,所以我们通常也将Lua程序称为Lua脚本。lua有以下一些特性:
但凡学个编程语言都逃不过hello world
的命,我们还从hello world开始吧。如果你的设备是Mac,可以打开终端,输入lua并回车,就进入了lua的命令行模式,如下
Last login: Sun Feb 2 16:50:11 on ttys004
xxxx ~ $ lua
Lua 5.3.3 Copyright (C) 1994-2016 Lua.org, PUC-Rio
> print("hello world")
hello world
>
在lua中我们通过print()
方法输出想要的内容,入门完成了,下面切入正题。
Lua支持的数据类型很少,共8种,分别是:nil
、boolean
、number
、string
、function
、table
、userdata
和thread
。
是lua中的一个特殊的值,只有一个值nil,未定义的变量都是nil,可以将一个变量设置为nil来删除此变量的指向,下一个垃圾回收时将会释放这些资源(垃圾回收也称gc循环)
布尔值有true和false两个值,要注意的是在做条件判断时false和nil为否
,其他均为真
实数,Lua中没有整数和浮点数的概念,Lua可以处理任何长度的数而不用担心误差。
字符串,Lua是8位字节,所以字符串可以包含任何数值字符。你可以存储任意的二进制数据在一个字符串里。Lua中字符串是不可以修改的,你可以创建一个新的变量存放你要的字符串。
'hello world' -- 通过单引号创建字符串
"hello world" -- 通过双引号创建字符串,单引号双引号二者没什么区别
-- 通过[[...]]创建字符串,通常用来创建比较长的字符串
[[
hello
world
]]
-- 将数组转成字符串
tostring(10) -- "10"
-- 将字符串转成数字
tonumber("10") -- 10
-- 通过 .. 进行字符串拼接(这种做发比较低效,正常开发中有更高效的方式,后面我们会讲到)
"aa-" .. "bb-" .. "cc-" -- "aa-bb-cc-"
-- 字符串长度计算(两种方式)
local str = "hello"
#str -- 5
string.len(str) -- 5
特殊字符串: ( ) . % + - * ? [ ^ $
函数是第一类值(和其他变量相同),意味着函数可以存储在变量中,可以作为函数的参数,也可以作为函数的返回值。
-- 定义无参test函数
function test()
print("hello world")
end
-- 调用test函数
test() -- hello world
--------------------------------------------------
-- 定义带参testa函数
function testa(name)
print("hello ", name, " !")
end
-- 调用testa函数
testa("北京") -- hello 北京 !
--------------------------------------------------
-- 定义任意参数的testb函数
function testb(...)
-- 用局部变量arg接收参数
local arg = {...}
-- 高效的字符串拼接方式,此处暂不需要理解table.concat()是啥
local aimStr = table.concat(arg)
print(aimStr)
end
-- 调用testb函数
testb("aa-", "bb-", "cc") -- aa-bb-cc
--------------------------------------------------
-- 定义并使用匿名函数
function testc(num1, num2)
-- 定义匿名函数
function add(a, b)
return a + b
end
-- 调用匿名函数
add(num1, num2)
end
testc(10, 5) -- 15
--------------------------------------------------
-- 函数作为参数传递
function testd(num1, num2, block)
-- 如果block是个函数,则调用block
if type(block) == "function" then
block(num1 + num2)
end
end
testd(5, 10, function(result)
print(result) -- 15
end)
table是lua中唯一的数据结构,也是极其强大的数据结构,与其他语言分为数组和字典两种数据结构不同,lua中table由数组和哈希两部分组成,通过table来实现数组和字典。
更神奇的是,我们可以通过table构建类与对象,并通过table提供的一些骚操作来实现面向对象。
【注:table中数组部分的索引从1开始】
-- 创建空表
local t = {}
-- 给表添加key-value
t["name"] = "小明"
t["age"] = 18
t.addr = "北京市朝阳区望京SOHO" -- 用.取值赋值更方便
-- 给表添加数组部分
t[1] = "aaa"
t[2] = "bbb"
t[3] = "ccc"
-- 创建key-value表
local tt = {
name = "小明",
age = 18,
addr = "北京市朝阳区望京SOHO"
}
-- 创建list表
local ttt = {"aaa", "bbb", "ccc"}
-- 创建key-value和list并存的表
local tttt = {
"aaa",
"bbb",
"ccc",
name = "小明",
age = 18,
addr = "北京市朝阳区望京SOHO"
}
-- 表访问
print(t.name) -- 小明
print(t["age"]) -- 18
local key = "addr"
print(t[key]) -- 北京市朝阳区望京SOHO
print(t[1]) -- aaa
local index = 2
print(t[index]) -- bbb
-- 输出表中的数组元素个数
print(#t) -- 3
顾名思义就是用户数据类型,用户通过C或C++自定义的数据结构,使用MLN开发过程中,所有桥接原生的数据结构在lua中都是userdata类型的
类似于线程,提供挂起和恢复等功能,可以方便的挂起或恢复一个操作。
在一个lua虚拟机中我们无法做到真正意义上的多线程,因为lua虚拟机是一个栈结构,所有的操作在虚拟机内部都是出栈和入栈操作。为了保证lua栈的线程安全,一般一个虚拟机只跑在固定的一个线程,在MLN中虚拟机是跑在主线程的,所有的异步操作由原生bridge完成,并在主线程将结果回调至虚拟机中。
随着大家对lua认识的进一步加深,慢慢会对这些有更深的了解,目前大可不必拘泥于这一点。
原文goto